【WEB3.0零基础转行笔记】Solidity编程篇-《Foundry基础》:第1讲:Foundry简易存储

目录

[1.1 Rocket Pool 介绍](#1.1 Rocket Pool 介绍)

[1.1.1 Rocket Pool 是什么?](#1.1.1 Rocket Pool 是什么?)

[1.1.2 为什么需要 Rocket Pool?](#1.1.2 为什么需要 Rocket Pool?)

[1.1.3 Rocket Pool 的核心机制](#1.1.3 Rocket Pool 的核心机制)

[1.1.4 Rocket Pool 的核心优势](#1.1.4 Rocket Pool 的核心优势)

[1.1.5 Rocket Pool 与 DeFi 生态](#1.1.5 Rocket Pool 与 DeFi 生态)

[1.1.6 对 Solidity 开发者的意义](#1.1.6 对 Solidity 开发者的意义)

[1.1.7 如何开始使用 Rocket Pool](#1.1.7 如何开始使用 Rocket Pool)

[1.1.8 总结](#1.1.8 总结)

[1.2 简介-Foundry简易存储](#1.2 简介-Foundry简易存储)

[1.2.1 Foundry基础](#1.2.1 Foundry基础)

[1.2.2 什么是 Foundry?](#1.2.2 什么是 Foundry?)

[1.2.3 Visual Studio Code](#1.2.3 Visual Studio Code)

[1.2.4 Foundry 与 Hardhat、Truffle对比](#1.2.4 Foundry 与 Hardhat、Truffle对比)

[1.3 开发环境搭建(Mac,Linux)](#1.3 开发环境搭建(Mac,Linux))

[1.3.1 VS Code 终端](#1.3.1 VS Code 终端)

[1.3.2 Git 安装](#1.3.2 Git 安装)

[1.4 开发环境搭建(Window)](#1.4 开发环境搭建(Window))

[1.4.1 VS Code 终端](#1.4.1 VS Code 终端)

[1.4.2 VS Code 终端](#1.4.2 VS Code 终端)

[1.4.3 什么是 WSL?](#1.4.3 什么是 WSL?)

[1.4.4 如何安装WSL?](#1.4.4 如何安装WSL?)

[1.4.5 使 Visual Studio Code 与 WSL 兼容](#1.4.5 使 Visual Studio Code 与 WSL 兼容)

[1.4.6 Git 安装](#1.4.6 Git 安装)

[1.5 使用 Gitpod 在云端进行开发](#1.5 使用 Gitpod 在云端进行开发)

[1.6 本地设置](#1.6 本地设置)

[1.7 Foundry 搭建](#1.7 Foundry 搭建)

[1.7.1 准备你的终端](#1.7.1 准备你的终端)

[1.7.2 保持终端整洁](#1.7.2 保持终端整洁)

[1.7.3 理解垃圾桶图标和 X 图标](#1.7.3 理解垃圾桶图标和 X 图标)

[1.7.4 安装 Foundry](#1.7.4 安装 Foundry)

[1.7.5 验证安装](#1.7.5 验证安装)

[1.7.6 Foundryup 不运行?](#1.7.6 Foundryup 不运行?)

[1.8 测试](#1.8 测试)

[1.9 VS Code 设置](#1.9 VS Code 设置)

[1.9.1 安装 VS Code 扩展](#1.9.1 安装 VS Code 扩展)

[1.9.2 将 AI 集成到我们的工作中](#1.9.2 将 AI 集成到我们的工作中)

[1.9.3 其他重要的 VS Code 提示](#1.9.3 其他重要的 VS Code 提示)

[1.9.4 更多设置......](#1.9.4 更多设置……)

[1.10 创建一个新的Foundry项目](#1.10 创建一个新的Foundry项目)

[1.10.1 更多设置](#1.10.1 更多设置)

[1.10.2 创建新项目](#1.10.2 创建新项目)

[1.11 Foundry设置(Window/WSL)](#1.11 Foundry设置(Window/WSL))

[1.11.1 简介](#1.11.1 简介)

[1.11.2 WSL 设置](#1.11.2 WSL 设置)

[1.11.3 Visual Studio Code](#1.11.3 Visual Studio Code)

[1.12 VS Code Solidity设置](#1.12 VS Code Solidity设置)

[1.12.1 如何在 VS Code 中格式化 Solidity 代码](#1.12.1 如何在 VS Code 中格式化 Solidity 代码)

[1.12.2 VS Code 扩展的强大之处](#1.12.2 VS Code 扩展的强大之处)

[1.12.3 重要提示:请确保下载正确的扩展!](#1.12.3 重要提示:请确保下载正确的扩展!)

[1.12.4 配置默认格式化器](#1.12.4 配置默认格式化器)

[1.12.5 使用"保存时格式化"自动化工作流程](#1.12.5 使用“保存时格式化”自动化工作流程)

[1.12.6 手动控制与故障排除技巧](#1.12.6 手动控制与故障排除技巧)

[1.13 使用 Foundry 编译智能合约](#1.13 使用 Foundry 编译智能合约)

[1.13.1 编译智能合约:Foundry 控制台编译过程指南](#1.13.1 编译智能合约:Foundry 控制台编译过程指南)

[1.13.2 更多终端使用技巧](#1.13.2 更多终端使用技巧)

[1.14 测试](#1.14 测试)

[1.15 使用 Anvil 在本地部署智能合约](#1.15 使用 Anvil 在本地部署智能合约)

[1.15.1 部署智能合约](#1.15.1 部署智能合约)

[1.15.2 Ganache](#1.15.2 Ganache)

[1.15.3 配置 MetaMask](#1.15.3 配置 MetaMask)

[1.16 如何想MetaMask添加新网络](#1.16 如何想MetaMask添加新网络)

[1.17 使用 Forge 在本地部署智能合约](#1.17 使用 Forge 在本地部署智能合约)

[1.17.1 部署到本地区块链](#1.17.1 部署到本地区块链)

[1.18 重要提示:私钥安全(第一部分)](#1.18 重要提示:私钥安全(第一部分))

[1.18.1 练习私钥安全](#1.18.1 练习私钥安全)

[1.18.2 您的安全承诺](#1.18.2 您的安全承诺)

[1.19 使用Anvil在本地部署智能合约](#1.19 使用Anvil在本地部署智能合约)

[1.19.1 使用脚本通过 Anvil 在本地部署智能合约](#1.19.1 使用脚本通过 Anvil 在本地部署智能合约)

[1.20 什么是交易](#1.20 什么是交易)

[1.20.1 关于区块链交易的更多内容](#1.20.1 关于区块链交易的更多内容)

[1.21 重要提示:私钥安全(第二部分)](#1.21 重要提示:私钥安全(第二部分))

[1.21.1 如何不在命令行中暴露你的私钥](#1.21.1 如何不在命令行中暴露你的私钥)

[1.21.2 如何不在命令行中暴露你的私钥](#1.21.2 如何不在命令行中暴露你的私钥)

[1.21.3 如何处理生产代码中的这个问题?](#1.21.3 如何处理生产代码中的这个问题?)

[1.22 永远不要使用.env文件](#1.22 永远不要使用.env文件)

[1.23 使用CLI与智能合约交互](#1.23 使用CLI与智能合约交互)

[1.23.1 通过命令行与 Foundry 的 Cast 工具与合约地址交互](#1.23.1 通过命令行与 Foundry 的 Cast 工具与合约地址交互)

[1.23.2 向区块链发送信息](#1.23.2 向区块链发送信息)

[1.23.3 从区块链读取信息](#1.23.3 从区块链读取信息)

[1.24 在测试网(Sepolia)上部署智能合约](#1.24 在测试网(Sepolia)上部署智能合约)

[1.24.1 使用 Foundry 和 Alchemy 将合约部署到测试网或主网](#1.24.1 使用 Foundry 和 Alchemy 将合约部署到测试网或主网)

[1.24.2 为测试网创建我们自己的 RPC URL](#1.24.2 为测试网创建我们自己的 RPC URL)

[1.24.3 修改我们的私钥](#1.24.3 修改我们的私钥)

[1.25 测试](#1.25 测试)

[1.26 在Etherscan上验证智能合约](#1.26 在Etherscan上验证智能合约)

[1.26.1 在区块浏览器上手动验证智能合约](#1.26.1 在区块浏览器上手动验证智能合约)

[1.27 项目收尾工作](#1.27 项目收尾工作)

[1.27.1 清理项目](#1.27.1 清理项目)

[1.27.2 格式化](#1.27.2 格式化)

[1.28 Foundry ZKsync](#1.28 Foundry ZKsync)

[1.28.1 Foundry ZKsync](#1.28.1 Foundry ZKsync)

[1.29 编译 Foundry ZKsync](#1.29 编译 Foundry ZKsync)

[1.30 Anvil ZKsync已更新](#1.30 Anvil ZKsync已更新)

[1.30.1 Anvil ZKSync 更新](#1.30.1 Anvil ZKSync 更新)

[1.31 ZKsync本地节点](#1.31 ZKsync本地节点)

[1.31.1 本地节点设置](#1.31.1 本地节点设置)

[1.31.2 部署](#1.31.2 部署)

[1.32 ZKsync本地部署](#1.32 ZKsync本地部署)

[1.33 交易类型](#1.33 交易类型)

[1.33.1 /broadcast 文件夹](#1.33.1 /broadcast 文件夹)

[1.34 为什么选择L2](#1.34 为什么选择L2)

[1.34.1 引言](#1.34.1 引言)

[1.34.2 Gas 用量](#1.34.2 Gas 用量)

[1.34.3 部署到 ZKsync Sepolia](#1.34.3 部署到 ZKsync Sepolia)

[1.35 炼金术导论](#1.35 炼金术导论)

[1.35.1 Alchemy:去中心化应用开发的变革者](#1.35.1 Alchemy:去中心化应用开发的变革者)

[1.35.2 什么是 Alchemy?](#1.35.2 什么是 Alchemy?)

[1.35.3 Alchemy 是如何工作的?](#1.35.3 Alchemy 是如何工作的?)

[1.35.4 在 Alchemy 上创建新账户](#1.35.4 在 Alchemy 上创建新账户)

[1.35.5 应用专属仪表板](#1.35.5 应用专属仪表板)

[1.35.6 内存池观察工具](#1.35.6 内存池观察工具)

[1.35.7 总结](#1.35.7 总结)

[1.36 总结一下,恭喜](#1.36 总结一下,恭喜)

[1.36.1 庆祝 Foundry 里程碑:我们近期项目的完整回顾](#1.36.1 庆祝 Foundry 里程碑:我们近期项目的完整回顾)

[1.36.2 快速回顾:项目中的关键收获](#1.36.2 快速回顾:项目中的关键收获)

[1.36.3 理解区块链上的合约部署与交互](#1.36.3 理解区块链上的合约部署与交互)

[1.36.4 展望未来](#1.36.4 展望未来)

[1.37 测试](#1.37 测试)


1.1 Rocket Pool 介绍

了解更多关于**Rocket Pool**的信息,请访问 https://rocketpool.net/。

Rocket Pool 项目是一个在以太坊生态中非常重要的去中心化质押协议。下面我将详细介绍 Rocket Pool 是什么、它如何工作、为什么重要,以及它与 Solidity 开发者之间的关系。

1.1.1 Rocket Pool 是什么?

Rocket Pool 是一个建立在以太坊区块链上的去中心化 质押 协议 。它的核心目标是让任何人都能以任意金额参与以太坊的权益证明(Proof of Stake)验证,同时获得质押收益,而无需运行自己的节点或拥有 32 个 ETH。简单来说,Rocket Pool 是一个连接普通 ETH 持有者和以太坊网络之间的桥梁。

1.1.2 为什么需要 Rocket Pool?

要理解 Rocket Pool 的价值,首先需要了解以太坊质押的基本规则:

(1)32 ETH 门槛:在以太坊上独立运行一个验证节点,需要锁定 32 个 ETH(按当前价格这是一笔相当大的资金)。

(2)技术要求:运行节点需要保持 24/7 在线、维护硬件、及时更新软件,否则可能被罚没(Slash)部分质押资金。

(3)中心化风险:如果大部分质押由中心化交易所(如 Coinbase、Binance)控制,会导致以太坊网络走向中心化。

Rocket Pool 通过去中心化的设计解决了这些问题,让质押变得人人可及。

1.1.3 Rocket Pool 的核心机制

1. 双代币模型

Rocket Pool 设计了两个核心代币:

rETH(流动性质押代币)

  • 当用户通过 Rocket Pool 存入 ETH 时,会获得等值的 rETH

  • rETH 代表用户对质押池的权益,其价值会随着质押收益的积累而增长

  • rETH 可以自由交易、转账,或在 DeFi 协议中使用(如作为抵押品),解决了传统质押中资金锁定的流动性问题

RPL(Rocket Pool 协议代币)

  • 这是协议的治理和效用代币

  • 节点运营商需要质押 RPL 作为额外保险,以激励他们诚实工作

  • RPL 持有者可以参与协议治理,投票决定参数调整、升级等事项

2. 节点运营商机制

Rocket Pool 允许两类参与者:

普通用户(质押者)

  • 存入任意数量的 ETH(可少于 32 个)

  • 获得 rETH 作为凭证

  • 被动获得质押收益

节点运营商

  • 需要具备技术能力并运行验证节点

  • 必须提供至少 16 个 ETH 的自有资金

  • 还需质押一定数量的 RPL 作为保险

  • 协议会从用户池中匹配另外 16 个 ETH,共同组成完整的 32 ETH 节点

  • 节点运营商除了赚取质押奖励,还能获得额外的 RPL 奖励

3. 智能合约架构

Rocket Pool 通过一组精心设计的智能合约实现这些功能:

  • 存款合约:接收用户 ETH,铸造 rETH

  • 矿池合约:管理节点创建、资金匹配和收益分配

  • RPL 质押合约:处理节点运营商的 RPL 质押和罚没逻辑

  • Oracle 网络:一组去中心化的预言机,负责向链上报告节点状态和网络数据

1.1.4 Rocket Pool 的核心优势

(1)低门槛参与

  • 普通用户无需 32 ETH 或专业知识

  • 最低存款额极低(通常只需 0.01 ETH),让任何人都能参与

(2)去中心化

  • 任何人都可以成为节点运营商,无需许可

  • 验证节点分布全球,避免单一实体控制过多验证者

  • 维护以太坊网络的核心价值理念

(3)流动性

  • 传统质押中,资金被锁定无法动用

  • rETH 可在二级市场交易,或用于 DeFi 借贷、流动性挖矿

  • 用户既获得质押收益,又保留资金灵活性

(4)安全性

  • 协议经过多次专业审计

  • RPL 罚没机制增加节点作恶成本

  • 节点运营商和用户资金分离,用户资金受协议保护

  • 成熟的保险机制和故障处理流程

(5)透明性

  • 所有交易和合约状态都在链上可查

  • 收益分配完全由智能合约自动执行,无人为干预

  • 任何人都可以验证协议运行情况

1.1.5 Rocket Pool 与 DeFi 生态

Rocket Pool 不仅是质押协议,还是 DeFi 生态系统的重要基础设施:

(1)rETH 的广泛应用

  • rETH 已在 Curve、Uniswap、Balancer 等主流 DEX 上建立流动性池

  • 可在 Aave、Compound 等借贷协议中作为抵押品

  • 参与流动性挖矿获得额外收益

(2)"Curve 战争" 的参与者

  • 与 Curve 等协议深度集成,rETH 持有者可参与流动性激励

  • RPL 持有者可通过治理影响协议发展方向

(3)流动性质押衍生品赛道

  • 与 Lido、Frax 等并列为主要的流动性质押协议

  • 在去中心化程度上具有独特优势(Lido 有多签风险,Rocket Pool 完全无需信任)

1.1.6 对 Solidity 开发者的意义

学习 Rocket Pool 对 Solidity 开发者有以下几个价值:

(1)复杂 DeFi 协议的范例

  • 研究其双代币模型、罚没机制、收益分配的智能合约实现

  • 理解如何设计多角色、多合约的复杂系统

(2)去中心化治理实践

  • RPL 治理机制的实现方式

  • 时间锁、投票、提案执行等模式

(4)Oracle 集成

  • 如何安全地引入链外数据(节点状态、网络信息)

  • Oracle 网络的去中心化设计

(5)安全最佳实践

  • 如何防范重入攻击、数学精度问题

  • 多重审计和漏洞赏金计划

1.1.7 如何开始使用 Rocket Pool

如果你有兴趣参与或学习 Rocket Pool:

(1)作为用户

  • 访问官网 rocketpool.net

  • 连接钱包,存入 ETH 获得 rETH

  • 或者直接在 DEX 购买 rETH

(2)作为开发者

  • 阅读官方文档 docs.rocketpool.net

  • 查看 GitHub 上的智能合约源码

  • 加入 Discord 社区与其他开发者交流

(3)作为节点运营商

  • 需要有至少 16 ETH 并运行节点软件

  • 按照官方指南进行设置和配置

1.1.8 总结

Rocket Pool 是以太坊去中心化质押的重要基石,通过巧妙的经济模型和智能合约设计,让质押变得人人可及。它既解决了普通用户的参与门槛,又维护了以太坊的去中心化核心价值。对于 Solidity 开发者来说,Rocket Pool 是一个学习复杂 DeFi 协议设计和实现的绝佳案例,其双代币模型、罚没机制、治理系统等都值得深入研究。

1.2 简介-Foundry简易存储

1.2.1 Foundry基础

欢迎来到 Foundry 入门。在本课程中,你将掌握使用最佳 Web3 开发工具和框架(如Chainlink、Alchemy 和 Foundry)开始开发智能合约和协议所需的技能。

1.2.2 什么是 Foundry?

Foundry是一个基于 Solidity 和 Rust 构建的现代化智能合约开发框架,其核心特点是极速的编译、测试速度完全Solidity原生 的开发体验。它摒弃了传统的 JavaScriptPython 胶合代码,让你直接用**Solidity** 编写测试、部署脚本和交互逻辑,并通过内置的命令行工具forgecast等实现从项目初始化、依赖管理、模糊测试到链上交互的全流程覆盖。相比 Hardhat 或 Truffle,Foundry通过Rust实现的高性能EVM执行引擎让测试运行快如闪电,同时其文档详尽且完全开源,成为越来越多追求效率和安全性的Web3开发者的首选框架。关于这个强大工具的最佳简短描述可以在 Foundry Book中找到。

Foundry manages your dependencies, compiles your project, runs tests, deploys, and lets you interact with the chain from the command-line and via Solidity scripts.

请花点时间将 Foundry Book 添加为书签。它是最全面的资源,能解答你的所有问题。在你学习的过程中,它会非常方便。

Foundry 有许多优点,例如:

  • 它利用 Rust 进行编译,与 Hardhat 或 Brownie 等框架相比,构建速度显著更快。

  • 它完全基于 Solidity,无需学习其他编程语言。

  • 它的文档非常全面。

1.2.3 Visual Studio Code

在整个课程中,我们将使用 Visual Studio Code 来编写、测试、部署我们的智能合约并与之交互。Visual Studio Code 是一款轻量级、功能强大的源代码编辑器,可在 Windows、macOS 和 Linux 上使用。它拥有全面的扩展生态系统,使其成为智能合约开发的最佳选择之一。

1.2.4 Foundry 与 Hardhat、Truffle对比

Foundry、Hardhat 和 Truffle 是 Solidity 开发中最主流的三个框架,它们在设计理念、性能表现和适用场景上有着显著差异。以下是基于最新技术发展和实测数据的详细对比:

1、核心架构与性能对比

维度 Foundry Hardhat Truffle
核心语言 Rust + Solidity JavaScript/TypeScript JavaScript
测试语言 Solidity JS/TS JS/TS
编译速度 极快(3.8秒/50合约) 快(7.2秒/50合约) 中等(12.3秒/50合约)
调试能力 EVM操作码级 存储槽级 + 详细堆栈追踪 基础操作码级
学习曲线 中等(Solidity原生) 平缓(JS生态) 平缓(教程丰富)

2、三大框架的深度剖析

(1)Foundry:速度与测试之王

核心优势

  • 极速编译: 采用Rust编写,并行编译技术使大型项目编译速度比**Hardhat**快近一倍,比Truffle快三倍以上

  • **Solidity原生测试:**测试代码直接用Solidity编写,无需在JS和Solidity之间切换上下文,更贴近EVM思维

  • **内置高级测试能力:**模糊测试(Fuzz Testing)、不变性测试(Invariant Testing)是原生功能,可自动生成随机输入攻击合约。

  • **Gas优化:**字节码优化功能可减少15%的Gas消耗

适用场景

  • 安全敏感型项目(DeFi协议、跨链桥)

  • 需要深度测试和形式化验证的高价值合约

  • 审计公司和安全研究团队

局限:纯命令行交互模式对新手有一定门槛,学习时间比 Hardhat 多约62%;企业级部署功能不如Hardhat完善。

(2)Hardhat:企业级调试标准

核心优势

  • 卓越的调试体验:详细的堆栈追踪将交易回滚映射回源代码行,错误信息可读性强,是诊断复杂合约行为的最佳工具;

  • 主网分叉功能:可在本地完美复制主网状态进行测试,对DeFi协议开发至关重要;

  • 插件生态:最丰富的插件系统,与Ethers.js、OpenZeppelin、Tenderly等深度集成;

  • TypeScript支持:完善的类型定义,可在部署前捕获大量错误;

适用场景

  • 复杂DeFi协议和大型dApp开发

  • 需要前端集成的全栈项目

  • 企业级团队,特别是已有Web2/JS技术栈的团队

局限:JavaScript层导致测试执行速度较慢;模糊测试依赖插件而非原生;内存泄漏问题在长时间测试运行中偶有发生。

(3)Truffle:结构化老兵

核心优势

  • 稳定性:自2015年存在,进入维护模式但极其稳定,适合长期项目

  • 迁移系统:结构化的部署脚本,对多阶段发布和版本控制友好

  • 学习资源:教程最丰富,42%的新开发者选择Truffle作为首个框架

  • Ganache集成:图形化的本地区块链,可视化操作友好

适用场景

  • 学习Solidity的初学者

  • 需要严格部署顺序的遗留项目

  • 监管严格、需要规范流程的企业环境

局限:速度最慢,编译850合约/分钟,每笔交易2.3秒;插件生态不如Hardhat活跃;Ganache正被Hardhat Network和Anvil替代。

3、开发者决策矩阵

评估维度 Foundry Hardhat Truffle
编译速度 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐
调试深度 ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐
测试能力 ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐
学习曲线 ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
插件生态 ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
企业适用性 ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐

4、实际应用建议

专业团队的组合拳, 越来越多专业团队采用 Foundry + Hardhat 的组合策略:

  • Foundry:负责核心合约编写、深度测试和性能优化

  • Hardhat:处理部署脚本、前端集成和主网分叉测试

根据项目阶段选择:

原型验证阶段:Remix快速验证,或 Hardhat 轻量启动;

核心开发阶段:Foundry主攻,利用其测试能力确保安全;

集成部署阶段:Hardhat负责,利用其生态与前端对接;

长期维护阶段:Truffle可选,稳定性优先;

总结:没有绝对的"最佳"框架,只有最适合你项目需求的选择。对于追求极致性能和安全的项目,Foundry是不二之选;对于需要丰富生态和调试体验的企业级应用,Hardhat更合适;对于初学者或稳定维护的遗留项目,Truffle依然可靠。

1.3 开发环境搭建(Mac,Linux)

Windows 用户请前往 下一课。

Mac 和 Linux 用户请在此下载 VS Code。

设置过程非常简单。 如果你是第一次使用 VS Code,请花些时间浏览一下 "VS Code 入门" 指南。这些宝贵的提示可以帮助你清除在即将到来的编程冒险中的许多障碍。此外,为了更好地掌握 VS Code 的使用,可以考虑学习 freeCodeCamp 提供的 Visual Studio Code 速成课程

1.3.1 VS Code 终端

VS Code 有一个内置的终端模拟器,通常简称为 VS Code 终端。它直接在 VS Code 内提供了一个命令行界面环境,允许你与操作系统交互并运行各种工具和实用程序。

你可以同时打开多个终端,运行不同的 shell,包括 bash、Powershell、WSL 以及更多你已配置的 shell。

使用 + 按钮创建新终端,或使用垃圾桶按钮关闭当前终端。

无论你是为了开发工作还是安全工作学习 Foundry,快速行动是提高效率的关键之一。VS Code 在键盘快捷键方面非常灵活,你可以在此处 此处了解更多。

1.3.2 Git 安装

无论你是已安装但需要更新,还是需要全新安装,最好的方法是访问 Git Book 并按照那里的说明进行操作。

1.4 开发环境搭建(Window)

请从此处下载 VS Code

设置过程非常简单。 如果你是第一次使用 VS Code,请花些时间浏览一下 "VS Code 入门" 指南。这些宝贵的提示可以帮助你清除在即将到来的编程冒险中的许多障碍。此外,为了更好地掌握 VS Code 的使用,可以考虑学习 freeCodeCamp 提供的 Visual Studio Code 速成课程

1.4.1 VS Code 终端

VS Code 有一个内置的终端模拟器,通常简称为 VS Code 终端。它直接在 VS Code 内提供了一个命令行界面环境,允许你与操作系统交互并运行各种工具和实用程序。

你可以同时打开多个终端,运行不同的 shell,包括 bash、Powershell、WSL 以及更多你已配置的 shell。

使用 + 按钮创建新终端,或使用垃圾桶按钮关闭当前终端。

无论你是为了开发工作还是安全工作学习 Foundry,快速行动是提高效率的关键之一。VS Code 在键盘快捷键方面非常灵活,你可以在此处了解更多。

1.4.2 VS Code 终端

VS Code 内置了一个终端模拟器,通常简称为 VS Code 终端。它直接在 VS Code 中提供了一个命令行界面 (CLI) 环境,允许您与操作系统交互并运行各种工具和实用程序。

您可以同时打开多个终端,运行不同的 shell,例如 bash、Powershell、WSL 等等,具体取决于您的配置。

使用+按钮创建新终端,或使用垃圾桶按钮关闭当前终端。

无论您是学习**Foundry** 用于开发工作还是安全工作,快速行动都是提高效率的关键之一。VS Code 在键盘快捷键方面非常灵活,您可以++在这里++了解更多信息。

1.4.3 什么是 WSL?

WSL 代表 Windows Subsystem for Linux 。这是微软推出的一项功能,允许你在 Windows 机器上直接运行 Linux 环境。这意味着你可以将熟悉的 Linux 命令行工具和应用程序与你现有的 Windows 程序一起使用。为了确保你的代码能在各种使用基于 Unix 系统(如 MacLinux )的机器上运行,你会发现 WSL 非常有用。

1.4.4 如何安装WSL?

安装 WSL 非常简单,安装 WSL 的步骤如下:

**(1)**Microsoft Store 搜索并安装"Ubuntu"。

(2)查看当前已安装的 WSL 发行版

在 PowerShell 中运行:

复制代码
# 查看当前已安装的 WSL 发行版
wsl --list   

# 这将列出所有已安装的 Linux 发行版及其状态(是否运行、WSL 版本)。
wsl -l -v

注意:不需要手动额外启动一个"启动"步骤 。当你直接在 PowerShell 或命令提示符中输入 wsl 并回车时,系统会自动启动 Ubuntu 并进入 Linux 环境。

具体说明如下:

1)直接使用:在 PowerShell 或 CMD 中输入以下命令即可启动并进入 Ubuntu:

复制代码
wsl

或指定发行版:

复制代码
wsl ~ -d Ubuntu

2)首次启动特殊处理 :如果你是第一次启动这个 Ubuntu ,系统会提示你创建一个新的 UNIX 用户名和密码(与 Windows 登录凭据无关),这是 Linux 环境下的普通用户账户,用于后续的软件安装和文件操作。

3)查看状态 :运行 wsl -l -v 看到状态为 Stopped 是正常的,表示当前没有运行中的 WSL 实例。当你执行 wsl 命令后,状态会变为 Running

4)退出 WSL :在 Ubuntu 环境中输入 exit 即可退出回到 PowerShell,此时 Ubuntu 会再次变为 Stopped 状态。

总结 :你不需要执行任何额外的"启动"命令,直接 wsl 就同时完成了启动和进入。Ubuntu 已安装就绪,现在就可以开始使用了。

1.4.5 使 Visual Studio Code 与 WSL 兼容

1、第一种方法:

第一步:打开 VS Code 扩展面板

  • 启动 Visual Studio Code。

  • 点击左侧活动栏中的 扩展图标 (或按快捷键 Ctrl+Shift+X)打开扩展视图。

第二步:搜索并安装远程开发扩展

  • 在扩展搜索框中输入 Remote Development

  • 找到由 Microsoft 发布的 "Remote Development"扩展包 (通常包含 Remote -- SSH、Remote -- Containers、Remote -- WSL 三个扩展),点击 Install 进行安装。

  • 如果不想安装整个扩展包,也可以分别搜索并安装以下三个扩展:

    • Remote -- WSL

    • Remote -- SSH

    • Remote -- Containers

第三步:确认安装成功

  • 安装完成后,观察 VS Code 窗口的 左下角

  • 会出现一个新的图标,通常是一个蓝色的 >< 符号,鼠标悬停时显示 "打开远程窗口""Remote Window"

第四步:开始使用

  • 点击左下角的远程窗口图标,会弹出菜单,选择 "Connect to WSL" (连接到 WSL)。

  • VS Code 将重新启动并连接到 WSL 环境,此时你可以在 WSL 的 Linux 文件系统中直接创建、编辑和运行项目。

这样,你的 VS Code 就与 WSL 无缝集成了,可以在 Windows 中享受 Linux 开发环境的便利。

2、第二种方法:

(1)在 **Windows **终端中,打开一个新的 Ubuntu 终端。

(2)通过输入以下命令创建一个新文件夹:

复制代码
mkdir solidity-course

(3)切换目录到新创建的文件夹

复制代码
cd solidity-course/

(4)通过在终端中输入以下命令在文件夹内打开 VS Code

复制代码
code .

(5)成功!你刚刚创建了一个使用 WSL 的 VS Code 新实例。如果你在屏幕左下角看到一个带有 WSL Ubuntu 字样的小横幅,说明一切正确。

重要提示: 当你在 Windows 内的文件夹(例如文档中的 Development 文件夹)中进行项目操作时,务必了解 WSL 控制台只能访问 WSL 实例内部的本地文件。因此,建议将文件保存在 WSL 实例内部,以实现更快的通信速度和便利性。

1.4.6 Git 安装

无论你是已安装但需要更新,还是需要全新安装,最好的方法是访问 Git Book 并按照那里的说明进行操作。

通过调用命令检查你的 Git 安装

复制代码
git --version

太棒了!你已经准备好学习下一课了。

1.5 使用 Gitpod 在云端进行开发

**重要提示:**这不是开发智能合约的理想方式。使用 Gitpod 时,切勿共享密钥或暗语等私密信息。如果您希望继续拥有相关账户的所有权,就应该这样做。

Gitpod 是一个在线平台,提供基于云的预配置开发环境,专为使用 Git 代码库而设计。它类似于 Remix IDE,但它允许你在远程服务器上的浏览器中运行 VS Code。

前往++Gitpod 网站++ 并点击Continue with Github。之后,您就可以使用稳定版的 VS Code,从 Github 存储库开始创建一个新的工作区。

你会惊讶地发现它看起来和 VS Code 一模一样。你还可以选择在 VS Code 桌面版中打开 Gitpod。

所有操作都与 VS Code 相同,因此您应该能够使用相同的命令运行任何内容。

Gitpod 提供了一些非常棒的入门++资源++;

简单来说,Gitpod 是一个能让你在浏览器里直接运行完整开发环境(比如 VS Code)的云服务平台。它的核心作用是为开发者提供即时的、预配置好的编码环境,省去本地安装配置的麻烦。

具体来说,它的作用体现在以下几个方面:

**(1)提供标准化的开发环境:**你可以为项目配置好所有依赖(比如 Node.js、Solidity 编译器、Foundry 等)。当任何人(包括未来的你)点击一个链接,就能在浏览器里打开一个完全配置好的 VS Code 环境,代码和依赖都准备就绪,直接开始编码。这完美解决了"在我电脑上能运行"的问题。

**(2)让开发环境随手可得:**你不需要在自己的电脑上安装任何开发工具,只需要一个浏览器和网络,就能在几乎任何设备上(包括平板、甚至是 Chromebook)进行开发。所有计算都在云端服务器进行,不影响本地电脑性能。

**(3)与 Git 仓库无缝集成:**Gitpod 的工作区是基于 Git 仓库(比如 GitHub)创建的。你可以从任何仓库的任意分支直接启动一个环境,并且 Gitpod 会自动加载项目特定的配置。完成编码后,你可以直接提交和推送代码,无需离开浏览器环境。

**(4)支持临时性开发和协作:**你可以创建一个用于测试某个 Pull Request 的临时环境,用完就关掉,不占用本地资源。同时,你也可以生成一个链接分享给同事,对方可以直接进入你正在工作的同一环境,方便进行结对编程或调试。

在智能合约开发的场景中,Gitpod 的作用尤其明显:想象你找到一份开源的 Solidity 项目,按照说明你可能要安装 Node.js、Hardhat、Foundry 等一系列工具。但如果项目配置了 Gitpod,你只需在仓库 URL 前加上 gitpod.io/#,一个配置好 Solidity 环境、Foundry 框架和所有依赖的 VS Code 就会在浏览器中打开,你立刻就能编译、测试和部署合约。

1.6 本地设置

为了保持终端界面整洁,特别是在内容变得混乱时,你可以输入命令 "clear" 然后按回车。或者,在 Mac 上使用快捷键 command + k,在 Linux 或 Windows 上使用 control + k

理解 VS Code 终端中 垃圾桶 图标和 x 图标之间的区别很重要:点击 x 图标会隐藏/显示终端,重新打开时所有之前的内容仍然可见。而点击 垃圾桶 图标则会终止当前的终端会话。当你重新打开它时,你将看到一个全新的、空白的会话。

1.7 Foundry 搭建

欢迎阅读这份关于安装和操作 Foundry 的实用指南。Foundry 是一个多功能工具,它将为你的开发者之旅增添全新的命令行便捷性。无论你使用的是 Windows、Linux 还是 MacOS,我们都会提供相应的说明和技巧。所以,请放松心情,泡杯咖啡,让我们一起开始吧。

1.7.1 准备你的终端

首先,最重要的是。在我们深入安装 Foundry 之前,请确保你的终端已经正确设置。

如果你使用的是 Windows,你应该能看到像 WSLUbuntu 这样的字样。一旦你的终端环境准备就绪,就该学习一些快速技巧来帮助你简化工作流程了。

1.7.2 保持终端整洁

当命令在终端中堆积时,事情会变得有点让人不知所措。只需输入 clear 并按 Enter 键即可清除屏幕。或者,如果你使用的是 Mac,可以使用 Ctrl + K;如果你使用的是 Linux 或 Windows,可以使用 Ctrl + K

**专业提示:**这是我最喜欢且一直使用的键盘快捷键之一。

1.7.3 理解垃圾桶图标和 X 图标

终端中的垃圾桶按钮和 X 按钮功能不同。点击 X 只是隐藏终端,但会保留之前所有的代码行。而点击垃圾桶则会终止当前终端中运行的所有进程。要打开一个全新的终端,点击垃圾桶,然后使用 切换终端 或通过 终端 > 新建终端 重新打开它。

1.7.4 安装 Foundry

终端设置完毕,并掌握了一些技巧之后,我们继续安装 Foundry。请访问Foundry 官网,在安装选项卡中获取安装 Foundry 的命令。

该命令大致如下所示:

复制代码
curl -L https://foundry.paradigm.xyz | bash && foundryup

将此粘贴到终端后按回车键。

注意:此操作需要联网才能进行,因为它会从 Foundry 官方网站下载。

1.7.5 验证安装

运行 curl 命令后,终端底部将出现一条输出信息,指示检测到的 shell 以及 Foundry 已添加到您的路径中。

例如,输出信息可能类似于:

(1)刷新当前终端的配置

虽然安装脚本已经修改了 ~/.bashrc 配置文件,但你需要重新加载配置打开新终端才能生效

在终端中运行:

复制代码
source ~/.bashrc

这会重新加载 ~/.bashrc 文件,使其中设置的 PATH 更新生效。

(2)再次尝试运行 foundryup 这步需要开启"~~~~科学上网~~~~"

复制代码
foundryup

如果成功,你会看到 Foundry 组件(forge、cast、anvil、chisel)开始下载和安装。

(3)验证安装

安装完成后,运行:

复制代码
forge --version

可以看到如下的内容:

复制代码
forge Version: 1.5.1-stable
Commit SHA: b0a9dd9ceda36f63e2326ce530c10e6916f4b8a2
Build Timestamp: 2025-12-22T11:39:01.425730780Z (1766403541)
Build Profile: maxperf

现在,有一点需要记住:当你点击右上角的垃圾桶图标时,它实际上会'移除'(终止)终端。相比之下,X 按钮只是将其隐藏。

1.7.6 Foundryup 不运行?

如果此命令无法运行,请不要惊慌。你可能遇到了路径问题,需要将 Foundry 添加到你的路径中。如果遇到此问题,请查看本课程相关 GitHub 仓库的第 6 课。如果那里没有调试提示,欢迎在课程的 GitHub 仓库上发起讨论。在此之前,请务必先检查是否已有类似的讨论。

尝试在终端中输入 forge --version。你是否收到了一个不受欢迎的输出信息,显示 Forge command found?这意味着你需要重新运行 Foundry 在安装期间提供的 source 命令。

注意: 大多数情况下 bashrc 文件会自动加载。但是,如果你的设置并非如此,以下行可以将所需的命令添加到你的 Bash profile 末尾。这将确保你的 bashrc 文件默认加载。

复制代码
cd ~
echo 'source /home/user/.bashrc' >> ~/.bash_profile

这取决于您的操作系统,请查看 Foundry 文档以获取详细说明。

**总结:**搞定了!恭喜你成功安装了 Foundry 并准备好了与之无缝配合的终端。请记住,在安装过程中遇到小问题是很正常的,尤其是当你刚接触这些时。如果你遇到任何问题,请随时通过 GitHub 与课程社区互动。

祝愿您在 Foundry 上享受更多轻松愉快的编码体验!

1.8 测试

1.9 VS Code 设置

1.9.1 安装 VS Code 扩展

1、打开扩展视图:

有两种方法可以做到这一点:

  • 点击 VS Code 左侧活动栏中的扩展图标。

  • 使用快捷键 Ctrl+Shift+X(Windows/Linux)Cmd+Shift+X(Mac)

2、浏览或搜索扩展:

  • 扩展视图默认会显示推荐的扩展。

  • 使用搜索栏按名称查找特定扩展。

3、安装扩展:

找到你想要的扩展后,点击"安装"按钮。VS Code 将处理下载和安装过程。

就这么简单!该扩展现在应该可以在 VS Code 中使用了。

1.9.2 将 AI 集成到我们的工作中

在开发过程中集成 AI 的最佳扩展之一是 GitHub Copilot。

虽然这是一项付费服务,但其基于 AI 的直观代码自动补全功能可能会为你带来革命性的改变。当然,你也可以根据自己的偏好选择其他 AI 扩展。

你可以在此处下载 GitHub Copilot。更多详细信息以及你关于 GitHub Copilot 问题的解答,请点击此处获取。

1.9.3 其他重要的 VS Code 提示

警惕白点,如果你看到它,说明你的工作尚未保存,这意味着你的项目可能不会按你期望的方式运行。

CTRL(CMD) + \ 可以打开/关闭你的终端。这相当于点击终端右上角的X 按钮。

X 按钮左侧的 垃圾桶 按钮会销毁终端,请务必始终记住这两个按钮的区别。

太好啦!本课程的设置部分到此结束。现在我们要进入有趣的部分了,即实际使用 Solidity 和 Foundry 开发项目。

1.9.4 更多设置......

在终端中运行以下命令:

复制代码
# mkdir创建目录或子目录
mkdir foundry-f23

# cd更改目录
cd foundry-f23

展望未来,建议你将所有代码仓库都存放在此文件夹中。这样,你就始终有一个可以查阅所有代码的固定位置。

1.10 创建一个新的Foundry项目

1.10.1 更多设置

确保我们在上一课创建的文件夹中。

提醒: 我们运行了以下命令

复制代码
mkdir foundry-f23
cd foundry-f23

现在请输入以下命令:

复制代码
mkdir foundry-simple-storage-f23
cd foundry-simple-storage-f23

通过按 Tab 键,你可以让 cd 命令变得更快捷------只需输入目标名称的前几个字母后按下 Tab 键即可。Tab 键可以让你自动补全许多命令/路径。如果你输入 code .,一个新的 VS Code 实例将会打开,并将 foundry-simple-storage-f23 作为默认路径。

你可以在左侧边栏看到此文件夹的内容。请尝试以下命令:

复制代码
touch randomFile.txt

这将创建一个 randomFile.txt,如果你想删除它,请输入:

复制代码
rm randomFile.txt

终端在移动/打开/创建目录/文件、更改路径以及一般运行程序方面非常灵活。如果你想学习如何更快速地操作,我建议你学习这个教程

1.10.2 创建新项目

创建新 Foundry 项目的方法是运行 forge init 命令。这将在你当前的工作目录中创建一个新的 Foundry 项目。如果你想让 Foundry 在一个新文件夹中创建项目,可以输入 forge init 新文件夹名称。请记住,默认情况下 forge init 期望目标文件夹为空。如果你的文件夹不为空,则必须运行 forge init --force

如果遇到与 Git 配置相关的错误,请确保已配置你的用户名和邮箱。

复制代码
git config --global user.email "yourEmail@provider.com"
git config --global user.name "yourUsername"

好了,你的文件夹应该如下所示:

但这都是什么意思?

  • lib 文件夹是所有依赖项安装的地方,在这里你会看到例如:

    • forge-std(用于测试和脚本编写的 Forge 库)

    • openzeppelin-contracts(经过最严格实战检验的智能合约库)

    • 以及更多其他库,具体取决于你需要/安装的内容

  • scripts 文件夹存放你所有的脚本

  • src 文件夹是你放置所有智能合约的地方

  • test 文件夹存放你所有的测试文件

  • foundry.toml 为 Foundry 提供配置参数

稍后会详细介绍这些文件夹和文件。

请在 src 上右键单击,点击新建文件,将其命名为 SimpleStorage.sol。然后将提供的代码复制进去。

最后,请删除 Counter.s.solCounter.solCounter.t.sol。这些文件是 Foundry 在创建新项目时默认提供的一组基础智能合约。

1.11 Foundry设置(Window/WSL)

~~~~这部分内容在上面已经完成安装~~~~

1.11.1 简介

大家好 👋,我是 Vasily,我将担任你们所有 Windows 开发课程的讲师。在指导你们安装、运行和配置各种 Windows 工具的过程中,你们会经常见到我。

1.11.2 WSL 设置

近年来,微软显著改善了其开发环境支持。然而,对于智能合约开发 来说,安装依赖项有时会比较棘手。为了简化这一过程,我们将使用 Windows Subsystem for Linux (WSL):这是一个更好的选择,因为它能在你的 Windows 机器上启用一个功能完备的类 Unix 控制台,从而简化了在基于 Unix 的环境中常用的工具和实用程序的使用。这种设置确保了与所有在基于 Unix 的系统(如 macOS 和 Linux)上运行的代码的兼容性。

要安装 WSL,你可以先打开 Windows 终端。在 Windows 11 上,按 Windows 键,输入"terminal",然后按 回车。在 Windows 10 上,你需要从 Microsoft Store 安装 Windows 终端(选择 Microsoft Corporation 的官方应用)。

安装完成后,打开终端并输入 wsl --install。此命令将启动安装过程。之后,重新启动你的计算机。重启后,终端将再次出现,提示你选择一个 Unix 用户名并设置密码。至此,WSL 将成功安装 👍。

1.11.3 Visual Studio Code

安装完 WSL 后,我们需要安装一个代码编辑器。我们将使用 Visual Studio Code(VS Code),有三种不同的安装方法:

(1)使用终端: 利用 winget,这是 Windows 11 上预装的包管理器。打开终端并输入 winget search VS Code 来查找所需的软件包。然后,执行 winget install Microsoft.VisualStudioCode 来安装 VS Code。

**(2)通过网页浏览器:**在网页浏览器中搜索 "Visual Studio Code",选择微软官方链接并下载安装程序。按照提示操作,接受用户协议并自定义所有安装选项。

**(3 )使用 VSCodium:**对于那些更喜欢独立性和隐私性的人来说,有一个名为 VSCodium 的开源替代品。它类似于 VS Code,但没有微软的遥测功能。从 GitHub 下载 VSCodium 安装程序,并按照类似的安装步骤进行操作。

选择最适合你需求的方法。在本课程中,我将使用微软官方的 Visual Studio Code。

1.12 VS Code Solidity设置

复制代码
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.19;

contract SimpleStorage {

    uint256 public favoriteNumber; // storage variable: it's stored in a section of the blockchain called "Storage"

    function store(uint256 _favoriteNumber) public {
        // the variable favorite number is updated with the value that is contained into the parameter `_favoriteNumber`
        favoriteNumber = _favoriteNumber;
    }
}

1.12.1 如何在 VS Code 中格式化 Solidity 代码

处理原始、未格式化的代码会严重拖累生产力。当你的 Solidity 代码看起来像一大块白色文本时,阅读、调试和维护就会变得极其困难。从变量中区分关键字,从注释中识别函数,以及理解整体结构都成了一件苦差事。

本课将指导你设置 Visual Studio Code 环境,以便自动格式化 Solidity 文件并对其应用语法高亮。学完之后,你就能将难以阅读的代码转变为整洁、专业且易于浏览的格式。

1.12.2 VS Code 扩展的强大之处

强大的 VS Code 设置核心在于其扩展市场。对于任何编程语言,扩展都提供了诸如智能代码补全、错误检查(linting)等基本功能,而对我们来说最重要的是语法高亮和代码格式化。

虽然有多个优秀的 Solidity 扩展可用,但本指南将重点介绍一个功能强大且得到广泛支持的扩展。

热门 Solidity 扩展:

要开始使用,请打开 VS Code 中的 扩展视图(点击侧边栏的图标或按 Ctrl+Shift+X),搜索"Solidity by Nomic Foundation",然后点击"安装"。你将立即看到你的 .sol 文件以颜色和高亮显示。

作为额外提示,如果你正在使用 Foundry,你的项目会包含一个 foundry.toml 配置文件。为了让它也能获得语法高亮,请安装 Even Better TOML 扩展。

1.12.3 重要提示:请确保下载正确的扩展!

请务必做到:

  • 使用本课程提供的链接

  • 使用资源页面上的链接

  • 或者,核实你正在使用正确的扩展

曾发生过恶意扩展以相似名称上传到扩展市场的攻击事件。请始终仔细检查发布者和扩展的描述,以确保你安装的是正确的扩展。

以下是此类攻击的两个示例:

1.12.4 配置默认格式化器

安装扩展只是第一步,要实现自动格式化,你必须明确告诉 VS Code 将其作为 Solidity 文件的默认格式化器。这需要在你的用户设置文件中完成。

(1)使用快捷键 Cmd + Shift + P(在 macOS 上)或 Ctrl + Shift + P(在 Windows/Linux 上)打开命令面板。

(2)输入 settings.json,并从下拉菜单中选择 首选项:打开用户设置 (JSON)。这将打开你的全局 settings.json 文件。

(3)将以下 JSON 代码片段添加到文件中。如果文件中已有设置,请在最后一个条目后添加一个逗号,然后粘贴此代码。

复制代码
{
    // ... your other settings may be here

    "[solidity]": {
        "editor.defaultFormatter": "NomicFoundation.hardhat-solidity"
    }
}

让我们来解析一下这个配置:

  • "[solidity]" : 这是一个语言标识符。它指示 VS Code 将嵌套的设置仅应用于被识别为 Solidity 的文件(即带有 .sol 扩展名的文件)。

  • "editor.defaultFormatter" : 该属性为指定的语言设置默认的格式化工具。

  • "NomicFoundation.hardhat-solidity" **:**这是你安装的 Nomic Foundation 扩展的唯一标识符。

添加此代码后,记得保存 settings.json 文件。

1.12.5 使用"保存时格式化"自动化工作流程

**方法一:**保持代码整洁最有效的方法是每次保存时自动格式化。这消除了手动触发操作的需要,并确保你的代码始终保持结构良好。

(1)打开 VS Code 设置界面。你可以通过命令面板(首选项:打开设置 (UI))或点击左下角的齿轮图标来完成此操作。

(2)在设置页面顶部的搜索栏中,输入 format on save

(3)找到编辑器:保存时格式化 选项并勾选以启用它。

启用此设置后,在 Solidity 文件上只需按 Cmd + SCtrl + S 即可执行两个操作:它会保存文件内容并立即运行 Nomic Foundation 格式化器,清理缩进、间距和对齐。

**方法二:**直接添加如下的命令在文件中:

复制代码
"editor.formatOnSave": true

1.12.6 手动控制与故障排除技巧

虽然自动化功能很强大,但有时你可能需要对格式化进行更精细的控制。

  • **保存工作:**始终确保你的文件已保存。在 VS Code 中,未保存的文件会通过标签页中文件名旁的白点来指示。格式化和其他功能通常依赖于文件的已保存状态。

  • **手动格式化:**如果你不想使用"保存时格式化",你可以随时手动格式化一个文档。打开命令面板(Cmd/Ctrl + Shift + P)并运行 格式化文档 命令。

  • **不格式化直接保存:**在极少数情况下,你可能希望以其当前未格式化的状态保存文件。要执行此操作,请使用命令面板运行 文件:保存但不格式化 命令。

  • 故障排除: 如果格式化不起作用,首先要检查的是你的 settings.json 文件。扩展标识符(NomicFoundation.hardhat-solidity)中的拼写错误或缺少逗号都可能导致配置失效。请确保为 [solidity] 语言标识符设置了正确的默认格式化器。如果你仍然遇到问题,在线搜索或在开发者社区中提问通常可以快速找到解决方案。

1.13 使用 Foundry 编译智能合约

1.13.1 编译智能合约:Foundry 控制台编译过程指南

打开一个新终端。输入 forge buildforge compile 来编译项目中的智能合约。

编译完成后,你会在左侧的"资源管理器"标签页中看到一些新文件夹。其中一个文件夹名为 out。在这里,你可以找到智能合约的 ABI 以及 字节码 和许多有用的信息。

cache 文件夹也会出现。通常,此文件夹用于存储临时系统文件,以方便编译过程。但在本课程中,你可以放心地忽略它。

1.13.2 更多终端使用技巧

在你的 Solidity 开发/审计过程中,你会输入大量终端命令。每次进行更改并想测试时,你可能需要重新运行 forge build,然后可能用 forge test 进行测试,或者用 forge script 运行脚本,等等。一遍又一遍地输入所有这些命令既低效又耗时。更好的方法是使用 箭头键。输入以下命令:

复制代码
echo "I like Foundry"
echo "I love Cyfrin"
echo "Auditing is great"

现在按方向键 箭头键来浏览这 3 条命令。

好的,太棒了!我们学会了如何编译合约,但如何部署智能合约呢?

1.14 测试

1.15 使用 Anvil 在本地部署智能合约

1.15.1 部署智能合约

部署智能合约有多种方式和可选的环境。在使用 Foundry 框架进行开发时,最便捷、开箱即用的本地测试环境便是 Anvil------这是 Foundry 自带的轻量级本地测试网节点,它可以快速启动一个模拟区块链,供你进行合约部署、前端交互或通过 RPC 接口测试。只需在终端中输入 anvil 命令,即可立即启动该节点,获得一个与真实以太坊兼容的本地开发环境。

打开**Ubuntu** ,输入如下命令,打开**anvil**:

复制代码
anvil

你现在可以访问 10 个测试地址,每个地址预置了 10,000 ETH,并附有对应的私钥。

这个测试网节点始终监听 127.0.0.1:8545,这将成为我们在此部署智能合约时使用的 RPC_URL 参数。更多细节稍后介绍!

有关 Anvil 的更多信息,请参阅 此处

请按 Ctrl/CMD + C 关闭 Anvil。

在整个课程中,我们将使用 Anvil 来部署和测试智能合约,但在此之前,让我们快速检查一个中间步骤。

1.15.2 Ganache

甘纳许是一种用于糕点的釉料、糖霜、酱汁或馅料,通常由等重量的奶油和切碎的巧克力加热制成,先加热奶油,然后将其倒在巧克力上。

等等,不是那个甘纳许!是另一个甘纳许:

Ganache 是一个用于快速开发以太坊和 Filecoin 分布式应用程序的个人区块链。你可以在整个开发周期中使用 Ganache;让你能够在一个安全且确定性的环境中开发、部署和测试你的 dApp。

这样好多了!

请从此处下载 Ganache

对于使用 Windows WSL 的用户,请阅读此说明。在此环境中使用 Ganache 并不是一件容易的事。我们在后续课程中不会使用它,所以如果配置不好也不用担心。

点击 Quickstart Ethereum。瞧!一个全新的区块链诞生了。我们会得到一些地址,它们都有余额和私钥。

1.15.3 配置 MetaMask

要部署到自定义网络(例如你的本地主机),你需要 MetaMask。MetaMask 是一款流行的加密货币钱包和浏览器扩展,允许用户与以太坊区块链及其生态系统进行交互。如果你还没有安装,请从此处下载

请按照以下步骤操作:

(1)打开 MetaMask。

(2)点击**"三根横杠"**。

(3)然后选择"网络"。

(4)在这里,你会看到网络列表(以太坊、主网等),以及每个网络的详细信息。找到 RPC URL------这是关键。

RPC URL 本质上是我们发送交易时进行 API 调用的端点。对于你执行的每一笔区块链交易,你都是在向此处的内容发起 API 调用。

要将交易发送到你的自定义区块链,你需要将其添加为一个网络:

(1)点击"添加网络"

(2)滚动到网络列表的底部。

(3)点击"手动添加网络"。

(4)输入你的本地网络详细信息

  • 网络名称:Localhost

  • 新的 RPC URL:Ganache http://127.0.0.1:7545 或 Anvil http://127.0.0.1:8545(请确保始终添加 http://------这两个地址在你的机器上可能不同,请查阅 Ganache UI 或 Anvil 终端以获取准确的 RPC URL。)

  • 链 ID:Ganache 为 5777(有时为 1337),Anvil 为 31337------这两个值在你的机器上可能不同,请查阅 Ganache UI 或 Anvil 终端以获取准确的链 ID。

  • 货币符号:ETH

  • 区块浏览器 URL:-(我们新创建的区块链没有区块浏览器,而且当我们关闭 VS Code / Ganache 应用时,它很可能会消失)

太棒了!现在我们配置好了本地网络,下一步是将 Ganache 或 Anvil 中的可用账户之一添加到我们的 MetaMask 中。操作步骤如下

(1)回到账户界面

(2)点击"添加钱包"。

(3)点击"导入账户"。

(4)你将进入导入页面。粘贴你的 Ganache/Anvil 私钥,然后点击"导入"。

**注意:**请勿将此账户用于任何其他用途,不要在主网或任何其他真实区块链上与之交互或向其发送资产,仅在本地用于测试目的。所有人都可以访问它。

接下来我们将进一步讨论如何向 MetaMask 添加新网络。

1.16 如何想MetaMask添加新网络

便捷的是,MetaMask 提供了一种简单的方法来添加 EVM 兼容链。通过预先配置许多链,你只需点击左上角的 网络 按钮,然后点击 添加网络 并继续点击 添加,即可添加诸如 Arbitrum One 这样的链。令人欣喜的是,MetaMask 会完成所有繁琐的工作,为你填写所有必要的信息。点击 批准网络 即可确保网络成功添加。

步骤:

(1)点击左上角的网络按钮

(2)点击添加网络

(3)选择你想要的 EVM 兼容链

(4)点击添加

(5)确认所有必要信息已填写后,点击批准网络

但是,如果你想添加的链没有预配置,该怎么办呢?

很简单!你只需采用上一课中我们用来添加新的 Ganache 本地链的相同过程即可。

1.17 使用 Forge 在本地部署智能合约

SimpleStorage.sol文件

复制代码
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.19;

contract SimpleStorage {

    uint256 public favoriteNumber; // storage variable: it's stored in a section of the blockchain called "Storage"

    function store(uint256 _favoriteNumber) public {
        // the variable favorite number is updated with the value that is contained into the parameter `_favoriteNumber`
        favoriteNumber = _favoriteNumber;
    }
}

1.17.1 部署到本地区块链

方法一:在Ganache上部署智能合约

要了解更多关于 forge 的功能,在VSCode终端中输入如下命令:

复制代码
forge --help

命令:

**bind:**为智能合约生成 Rust 绑定

**bind-json:**通过 JSON 作弊码为项目结构体生成序列化/反序列化绑定

**build:**构建项目的智能合约 [别名: b, compile]

**cache:**管理 Foundry 缓存

**clean:**移除构建产物和缓存目录 [别名: cl]

**clone:**从 Etherscan 克隆合约

**compiler:**编译器工具

**completions:**生成 Shell 补全脚本 [别名: com]

**config:**显示当前配置 [别名: co]

**coverage:**生成覆盖率报告

create: 部署智能合约 [别名: c]

**doc:**为项目生成文档

**EIP712:**从给定文件为结构体生成 EIP-712 结构编码

**flatten:**将源文件及其所有导入扁平化为单个文件 [别名: f]

**fmt:**格式化 Solidity 源文件

**geiger 已弃用:**检测项目及其依赖中不安全作弊码的使用情况

**help:**打印此消息或指定子命令的帮助信息

**init:**创建一个新的 Forge 项目

**inspect:**获取智能合约的特定信息 [别名: in]

**install:**安装一个或多个依赖 [别名: i, add]

**lint:**检查 Solidity 源文件 [别名: l]

**remappings:**获取项目自动推断的重映射 [别名: re]

**remove:**移除一个或多个依赖 [别名: rm]

**script:**将智能合约作为脚本运行,构建可在链上发送的交易

**selectors:**函数选择器工具 [别名: se]

**snapshot:**为每个测试的 gas 使用量创建 gas 快照 [别名: s]

**soldeer Soldeer:**依赖管理器

**test:**运行项目的测试 [别名: t]

**tree:**显示项目依赖关系的树形可视化图 [别名: tr]

**update:**更新一个或多个依赖 [别名: u]

**verify-bytecode:**在 Etherscan 上验证已部署的字节码是否与源代码匹配 [别名: vb]

**verify-check:**在 Etherscan 上检查验证状态 [别名: vc]

**verify-contract:**在 Etherscan 上验证智能合约 [别名: v]

在结果列表中,我们将使用 create 命令。

在终端中输入 forge create --help 或点击此处以了解可用的配置选项。

尝试运行 forge create SimpleStorage。这应该会失败,因为我们没有指定几个必需的参数:

(1)我们部署到哪里?

(2)谁来支付 gas 费用/签署交易?

我们来解决这两个问题。

正如你在之前的课程中学到的,每个区块链(私有或公有)都有一个充当端点的 RPC URL(RPC 服务器)。当我们尝试部署智能合约时,forge 尝试使用 http://localhost:8545/,但那里并没有任何区块链。因此,让我们尝试通过指定我们想要部署的位置来部署智能合约。

请启动 Ganache 并点击 Quickstart Ethereum。复制 RPC 服务器 HTTP://127.0.0.1:7545。让我们再次运行 forge create,并指定正确的 rpc url。

复制代码
forge create SimpleStorage --rpc-url http://127.0.0.1:7545

此方法再次失败,表明:

访问本地钱包时出错。您是否设置了私钥、助记词或密钥库?

请尝试以下命令:

复制代码
Error accessing local wallet. Did you set a private key, mnemonic or keystore?

系统会要求您输入私钥,请粘贴 Ganache 中提供的私钥之一。粘贴密钥时,您不会看到文本或任何占位符,只需按 CTRL(CMD) + V,然后按 ENTER 键即可。

瞧!

你可以前往 Ganache,查看 区块交易 标签页,以了解你刚才所做操作的更多信息。

方法二:在Anvil上面部署智能合约

从现在起,我们所有的部署都将在 Anvil 上进行。但如果你更喜欢 Ganache,也可以随意使用它。

请执行以下操作:

(1)运行 clear

(2)运行 anvil

(3)按 + 按钮新建一个终端

(4)从 anvil 终端复制其中一个私钥

(5)运行 forge create SimpleStorage --interactive

从输出信息来看,这次部署并未成功

关键信息在于:

复制代码
Warning: Dry run enabled, not broadcasting transaction

这表明 forge create 命令以 dry run(试运行) 模式执行,只是模拟了交易,并没有实际将合约部署到 Anvil 本地区块链上。因此,虽然显示了交易详情和 ABI,但合约并未上链,你也不会在 Anvil 终端中看到新增的区块或交易记录。

为什么会出现 dry run?

  • 当使用 --interactive 选项时,forge 会先进入交互模式,但在你输入私钥后,它默认只执行 dry run,需要你确认后再实际广播(例如按 y 确认)。

  • 或者,如果你没有输入私钥就直接退出,也会保持 dry run 状态。

如何真正部署?这次我们不需要指定 --rpc-url ,因为 forge 默认使用 Anvil 的 RPC URL。

(6)前往 Anvil 终端并查看部署详情:

使用 forge create 进行部署的更明确的方式如下:

复制代码
forge create SimpleStorage --rpc-url http://127.0.0.1:8545 --private-key 0xac0974bec39a17e36ba46ab4d238ff94ab4c478cbde5efca78d7bf4f2ff80 --broadcast

我们添加了 --rpc-url 参数,不再依赖默认值;同时添加了 --private-key 参数,不再使用 --interactive 选项。

呼!内容真不少,但我们学到了非常重要的一点------如何在两个本地区块链上部署智能合约。接下来要学习的内容,将是本课程中至关重要的一环,甚至可以说是 最重要 的内容:私钥安全。

1.18 重要提示:私钥安全(第一部分)

1.18.1 练习私钥安全

以明文形式保存私钥是极其糟糕的做法。我们在上一课中使用的私钥是众所周知的本地测试密钥,你不应在主网上使用它们,将它们以明文保存是可以的。但任何其他私钥都应保密,尤其是你的生产密钥或与持有加密货币的账户相关联的密钥。

此外,将私钥保存在 bash 历史记录中也是非常糟糕的(按上箭头键就能看到你用于部署的密钥)。

你可以通过输入以下命令来删除历史记录:

复制代码
history -c

我们将在接下来的课程中详细讲解如何保护私钥。

1.18.2 您的安全承诺

现在是时候明确你对维护私钥安全的承诺了。创建一个名为"承诺书"的文件Promise.md。务必在这个文件中写下你的承诺:

复制代码
I promise to never use my private key associated with real money in plain text.

如果你觉得这样做没问题,可以考虑发一条推文来确认并巩固你的承诺。记得标记 @PatrickAlphaC 和 @CyfrinUpdraft 或该领域的其他专业人士,以此让自己负责。

私钥被黑客攻击是个人和项目损失巨额资金的最重要原因之一。你甚至不需要深入查找,就能看到这样的标题:

  • Ronin 黑客攻击---通过社会工程学获取私钥;

  • 早期加密投资者 Bo Shen 称其在钱包黑客攻击中损失 4200 万美元;

  • 4.77 亿美元的 FTX 黑客攻击:FTX 新任 CEO 透露,允许访问公司加密资产的私钥以未加密形式存储;一名前雇员披露,由于安全措施薄弱,Alameda Research 被盗超过 1.5 亿美元;

不要像那样!也许你并没有持有数百万资产,但你拥有的就是你的,别让它变成别人的!

在接下来的课程中,我们将学习如何使用 Alchemy 免费获取任何区块链的 RPC URL。我们还将深入探讨处理私钥的更安全方法。敬请期待!

1.19 使用Anvil在本地部署智能合约

1.19.1 使用脚本通过 Anvil 在本地部署智能合约

通过脚本部署智能合约特别方便,因为它提供了一种一致且可重复的可靠部署方式,并且其功能增强了对部署过程和代码本身的测试。

你很可能喜欢命令行方式,但脚本丰富了整个部署流程,带来了更多的功能和无与伦比的易用性。

Foundry 简化了整个流程,因为它是用 Solidity 编写的。这意味着我们的部署脚本也将用 Solidity 编写。区分 Solidity 作为合约语言和 Solidity 作为脚本语言至关重要。Foundry 还融入了超越智能合约领域的元素,提升了我们的 Solidity 体验。那么,让我们开始创建一个脚本来部署我们的简单存储合约吧。

在 Foundry 中,我们将脚本保存在 script 文件夹中。

请创建一个名为 DeploySimpleStorage.s.sol 的新文件。

使用 .s.sol 作为后缀是 Foundry 脚本的命名约定,在未来的课程中,当我们编写 Foundry 测试时,它们将使用 .t.sol 后缀。

有关 Foundry 脚本的更多最佳实践信息,请点击此处

打开新创建的文件。在这里,我们将编写一个用于部署 SimpleStorage 合约的 Solidity 脚本。

输入以下内容:

复制代码
// SPDX-License-Identifier: MIT

pragma solidity 0.8.19;

contract DeploySimpleStorage {
    
}

前两行不言自明。

我们声明了一个新合约,名为 DeploySimpleStorage

要使其被视为 Foundry 脚本,并能够访问 Foundry 所带来的扩展功能,我们需要从 "forge-std/Script.sol" 导入 Script,并让 DeploySimpleStorage 继承 Script

执行如下命令,下载将forge-std 依赖库:

复制代码
# 此操作最好开启科学上网
forge install foundry-rs/forge-std

注意: forge-std(也称为 Forge 标准库)是一组预编写的 Solidity 合约集合,旨在简化并增强 Foundry 开发框架内的脚本编写和测试功能。

此外,为了能够部署 SimpleStorage,我们还需要通过输入 import {SimpleStorage} from "../src/SimpleStorage.sol"; 来导入它。

复制代码
// SPDX-License-Identifier: MIT

pragma solidity 0.8.19;

import {Script} from "forge-std/Script.sol";
import {SimpleStorage} from "../src/SimpleStorage.sol";

contract DeploySimpleStorage is Script {
    
}

每个脚本都需要一个主函数,根据上面链接的最佳实践,该函数名为 run。当你运行 forge script 时,被调用的就是这个函数。

复制代码
// SPDX-License-Identifier: MIT
// 声明许可证,允许代码自由使用、修改和分发

pragma solidity 0.8.19;
// 指定 Solidity 编译器版本必须为 0.8.19,确保代码在该版本下编译

// 导入 Foundry 标准库中的 Script 合约,它提供脚本运行所需的基础功能
import {Script} from "forge-std/Script.sol";
// 导入我们要部署的目标合约 SimpleStorage
import {SimpleStorage} from "../src/SimpleStorage.sol";

/**
 * @title DeploySimpleStorage
 * @dev 使用 Foundry 脚本部署 SimpleStorage 合约
 * 该合约继承自 Script,可以在 Foundry 环境中运行,并通过 vm 作弊码控制交易广播
 */
contract DeploySimpleStorage is Script {
    /**
     * @dev 脚本的主函数,由 `forge script` 命令调用
     * @return SimpleStorage 返回部署好的 SimpleStorage 合约实例
     *
     * 该函数利用 Foundry 的作弊码 `vm.startBroadcast()` 和 `vm.stopBroadcast()` 来标记需要广播的交易范围。
     * 在此范围内使用 `new` 关键字创建的合约将会被部署到链上。
     */
    function run() external returns (SimpleStorage) {
        // 开始广播模式:在此之后的所有交易都会被记录并广播
        vm.startBroadcast();

        // 使用 `new` 关键字创建新的 SimpleStorage 合约实例,实际部署过程在此发生
        SimpleStorage simpleStorage = new SimpleStorage();

        // 停止广播模式:标记交易广播的结束点
        vm.stopBroadcast();

        // 返回新创建的合约实例,方便后续交互
        return simpleStorage;
    }
}

run 是一个外部函数,其返回值是 SimpleStorage 合约实例。

run 函数内部,我们会用到 vm 这个特殊关键字。vm 是 Foundry 框架提供的"作弊码"之一,因此仅在 Foundry 环境中有效。

vm.startBroadcast() 用于标记将要发送至 RPC URL 的交易列表的起始位置。

相应地,vm.stopBroadcast() 则标记该交易列表的结束位置。

在这两者之间,我们编写:

复制代码
SimpleStorage simpleStorage = new SimpleStorage();

new 关键字用于在 Solidity 中创建新的智能合约。

我们以 return simpleStorage; 结束函数。

请选择 Anvil 终端并按 CTRL(CMD) + C 将其停止。现在运行以下命令:

复制代码
forge script script/DeploySimpleStorage.s.sol

这应该会顺利完成,但如果您遇到任何相关错误,incompatible solidity versions in various files请确保两者都正确SimpleStorage.sol使用DeploySimpleStorage.s.solpragma solidity 0.8.19;

如果您想进一步拓展脚本编写方面的知识,请点击++此处。++

你应该得到以下输出:

复制代码
[⠆] Compiling...
[⠔] Compiling 2 files with 0.8.19
[⠒] Solc 0.8.19 finished in 1.08s
Compiler run successful!
Script ran successfully.
Gas used: 338569

== Return ==
0: contract SimpleStorage 0x90193C961A926261B756D1E5bb255e67ff9498A1

If you wish to simulate on-chain transactions pass a RPC URL.

价值百万美元的问题:如果我们没有传递 RPC URL,合约部署到了哪里?

如果未指定 RPC URL,Foundry 会自动启动一个 Anvil 实例,运行你的脚本(在我们的例子中即部署合约),然后终止该 Anvil 实例。

在终端中运行 anvil 命令,打开一个新终端并输入以下命令:

复制代码
forge script script/DeploySimpleStorage.s.sol --rpc-url http://127.0.0.1:8545

要获得以下输出:

另一个价值百万美元的问题:现在部署了吗?

答案:没有,输出结果表明这是一次模拟。但是,我们从中得到了一个新文件夹,broadcast 文件夹包含了关于不同脚本运行的信息,以防我们忘记细节。

按上箭头键,在末尾添加

复制代码
forge script script/DeploySimpleStorage.s.sol --rpc-url http://127.0.0.1:8545 --broadcast --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

现在我们的合约成功部署了!太棒了!

切换到 anvil 终端,你会看到:

太棒了!

通过这一课,我们一直在谈论一个叫做交易的东西,但交易到底是什么呢?敬请期待下一课来揭晓答案。

1.20 什么是交易

1.20.1 关于区块链交易的更多内容

在上一课中,我们一直在谈论交易,但从未解释过什么是交易。简单来说,交易记录了区块链上发生的活动细节。

在屏幕左侧的资源管理器选项卡中,你会找到一个名为 broadcast 的文件夹。Foundry 会将你所有的区块链交互保存到这里。dry-run 文件夹用于你在没有运行区块链时进行的交互(还记得那次我们在没有指定 --rpc-url 的情况下部署合约的情况吗?)。此外,这里的记录按 chainId 分隔。

注意: chainId 是分配给特定区块链网络的唯一标识符,用于区分不同的区块链,是确保区块链上交易和交互安全与完整性的关键参数。

进入 run-latest.json。 在这里,我们可以找到上一课中最后一次运行部署脚本的更多详细信息。它会显示诸如 transactionTypecontractNamecontractAddress 等信息。此外,在 transaction 部分,你可以看到我们实际发送到 RPC URL 的内容:

让我们逐一了解这些内容:

  • from 不言自明,它是我们用来签署交易的地址;

  • to 是接收方,在我们的例子中为 null 或 address(0),这是部署新智能合约时的标准目标地址;

  • gas 是消耗的 gas 量。你会看到十六进制值 0x714e1(或任何其他以十六进制格式表示的值);

快速提示: 普通人无法理解上面这样的十六进制值,但有一种快速方法可以将它们转换为常见的数字。在终端中运行以下命令:cast --to-base 0x714e1 deccast 是 Foundry 提供的一个非常 versatile 的工具,在终端中输入 cast --help 可以了解更多信息,或前往此处查看。

  • value 是交易价值,即我们发送的 ETH 数量。鉴于这笔交易是为了部署合约,这里的值是 0x00,但我们可以指定一个值,那将成为新部署合约的初始余额;

  • 这里的 data 是合约部署代码和合约代码。在上面的摘录中,这部分被截断了;

  • nonce 是为从特定账户发送的每笔交易分配的唯一标识符。nonce 用于确保每笔交易仅被处理一次,并防止重放攻击。nonce 随着每笔交易递增;

  • accessList 是以太坊的一项功能,用于优化交易的 gas 成本。它包含交易可能访问的地址和相关存储键的列表,允许 EVM 在交易执行期间更高效地计算存储访问的 gas 成本;

  • type 请暂时忽略此字段。

该列表中未列出但同样重要的其他值,即 vrs。这些是交易签名的组成部分,用于验证交易的真实性和完整性。

每当我们在区块链上发送交易时,都会进行签名,这时我们会使用到 私钥

重要提示: 每次更改区块链状态时,你都是通过交易来实现的。指示更改的内容是交易中的 data 字段。部署字节码、合约字节码和操作码将在未来的课程中讨论。

1.21 重要提示:私钥安全(第二部分)

1.21.1 如何不在命令行中暴露你的私钥

几节课前,我们使用以下命令部署了 SimpleStorage

复制代码
forge script script/DeploySimpleStorage.s.sol --rpc-url http://127.0.0.1:8545 --broadcast --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

1.21.2 如何不在命令行中暴露你的私钥

正如我们在第13课中解释的那样,将私钥以明文形式保存是非常糟糕的做法。除了使用 --interactive 参数之外,我们还能做些什么来避免这种情况呢?因为我们不想一直复制粘贴我们的私钥。

**大号加粗免责声明:**我们即将要做的事情对于开发目的来说是可以的,不要在这里放置真实的私钥,这在生产环境中是非常糟糕的。

在项目根目录创建一个名为 .env 的新文件。然后,进入 .gitignore 文件,确保 .env 在其中。

.env 文件将存放环境变量。这些变量具有敏感性,我们不想公开暴露。

打开该文件并将以下内容放入其中:

复制代码
PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
RPC_URL=http://127.0.0.1:8545

接下来运行 source .env。这将把上述环境变量添加到我们的 shell 中。现在运行 echo $PRIVATE_KEYecho $RPC_URL 来检查这些值是否存储在 shell 中。

现在我们可以安全地替换 forge script 命令中的参数:

复制代码
forge script script/DeploySimpleStorage.s.sol --rpc-url $RPC_URL --broadcast --private-key $PRIVATE_KEY

这不仅让你的私钥在命令行中不再明文显示,还能加快终端使用速度,想象一下你得反复复制粘贴 http://127.0.0.1:8545 这个 RPC URL 会多麻烦。用这种方式更整洁。

但没错,现在我们的私钥仍然以明文形式保存在 .env 文件中,这并不好。

1.21.3 如何处理生产代码中的这个问题?

Foundry 有一个非常好的选项叫做 keystore。要了解更多信息,可以在终端中输入 forge script --help。使用 forge script --keystore <路径> 可以让你指定一个加密存储文件的路径,该文件由密码加密。这样你的私钥就永远不会以明文形式出现。

我们达成以下共识:

(1)出于测试目的,只要你不将 .env 文件暴露在任何地方,就可以使用 .env 文件中的 $PRIVATE_KEY

(2)当涉及真实资金时,请使用 --interactive 选项或受密码保护的密钥库文件

关于将密钥存储在 .env 文件中,还有一件事。请查看 "THE_ENV_PLEDGE"。它起初是 GitHub 上的一项简单承诺,但现在已成为链上的永久誓言。请阅读该承诺并铸造你自己的灵魂绑定 NFT,向人们展示你对安全实践的承诺。注意安全!

1.22 永远不要使用.env文件

与此同时,一些事情发生了变化

在上一课中,我们向你展示了如何配置和使用 .env 文件来存储你的私钥和 RPC URL。但自那节课以来,已有一些新的进展,因此......你不应该再使用 .env 文件了。

使用 ERC2335 加密你的密钥

现在,让我们假设我们的私钥是:

0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbcd5efcae784d7bf4f2ff80(Anvil 中的第 0 号密钥)

在终端中输入以下命令:

复制代码
cast wallet import nameOfAccountGoesHere --interactive

理想情况下,不要在你的 VS Code 中执行此操作。

复制代码
forge script script/DeploySimpleStorage.s.sol --rpc-url $RPC_URL --broadcast --private-key $PRIVATE_KEY

系统会提示你输入私钥以及用于保护它的密码。你只需要执行一次,这非常棒!

如果你还记得,上一课中我们通过运行以下命令进行了部署:

复制代码
forge script script/DeploySimpleStorage.s.sol --rpc-url $RPC_URL --broadcast --private-key $PRIVATE_KEY

现在我们配置好了钱包,就可以按如下方式部署了:

复制代码
forge script script/DeploySimpleStorage.s.sol --rpc-url http://127.0.0.1:8545 --broadcast --account nameOfAccountGoesHere --sender 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266

系统会提示你输入密码。没有密码你将无法进行部署。

要查看所有已配置的钱包,可以调用以下命令:

复制代码
cast wallet list

使用以下命令清除你的终端历史记录,以免私钥残留其中:

复制代码
history -c

注意安全!保持警惕!不要丢失你的密钥。如果你看到自己的私钥以明文形式显示,那一定是操作有误。

1.23 使用CLI与智能合约交互

1.23.1 通过命令行与 Foundry 的 Cast 工具与合约地址交互

本节课建立在之前使用 forge script 部署 SimpleStorage 的基础上。我们已运行了 Anvil,且智能合约也已部署完成。

若没有完成部署的还需要完成一下的内容:

(1)添加 SimpleStorage.sol 代码

复制代码
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

contract SimpleStorage {
    uint256 public myFavoriteNumber;

    struct Person {
        uint256 favoriteNumber;
        string name;
    }

    Person[] public listOfPeople;

    mapping(string => uint256) public nameToFavoriteNumber;

    function store(uint256 _favoriteNumber) public virtual {
        myFavoriteNumber = _favoriteNumber;
    }

    function retrieve() public view returns (uint256) {
        return myFavoriteNumber; // 返回myFavoriteNumber状态变量的当前值
    }

    function addPerson(string memory _name, uint256 _favoriteNumber) public {
        require(bytes(_name).length > 0, "Name cannot be empty");
        
        require(_favoriteNumber > 0, "Favorite number must be positive");

        listOfPeople.push(Person(_favoriteNumber, _name));
        nameToFavoriteNumber[_name] = _favoriteNumber;
    }
}

DeploySimpleStorage.s.sol智能合约代码:

复制代码
// SPDX-License-Identifier: MIT
// 声明许可证,允许代码自由使用、修改和分发

pragma solidity ^0.8.19;

import {Script} from "../lib/forge-std/src/Script.sol";
import {SimpleStorage} from "../src/SimpleStorage.sol";

contract DeploySimpleStorage is Script {
    function run() external returns (SimpleStorage) {
        // 开始广播模式:在此之后的所有交易都会被记录并广播
        vm.startBroadcast();

        // 使用 `new` 关键字创建新的 SimpleStorage 合约实例,实际部署过程在此发生
        SimpleStorage simpleStorage = new SimpleStorage();

        // 停止广播模式:标记交易广播的结束点
        vm.stopBroadcast();

        // 返回新创建的合约实例,方便后续交互
        return simpleStorage;
    }
}

创建一个配置文件,并将如下的内容添加到文件中。

如果你想使用 .env 文件来存储私钥(虽然官方推荐使用加密的 keystore,但 .env 在开发测试中依然常见),可以按以下步骤配置:

复制代码
# 第一步:项目根目录下创建 .env 文件:
touch .env

# 第二步:编辑 .env 文件(将私钥和 RPC URL 写入)
PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
RPC_URL=http://127.0.0.1:8545   # Anvil 默认 RPC

⚠️ 安全警告

  • .env 中的私钥是明文 存储的,绝不要提交到 Git 仓库。务必在 .gitignore 中加入 .env

  • 仅建议在本地测试或私有环境中使用。生产环境或与他人协作时,务必使用 cast wallet 加密 keystore 的方式。

为什么课程说"再也不要用 .env"?

因为 .env 中的私钥是明文 ,一旦你的终端历史、日志或代码仓库泄露,私钥就会暴露。Foundry 推荐的 cast wallet import 会将私钥加密存储在 ~/.foundry/keystores/ 中,并设置密码保护,更加安全。

如果你希望继续使用 .env 进行快速本地测试,可以保留,但请务必意识到风险,并避免在真实资产或公共网络中使用。

(2)执行如下的命令部署智能合约

复制代码
forge script script/DeploySimpleStorage.s.sol --rpc-url $RPC_URL --broadcast --private-key $PRIVATE_KEY

部署成功后会出现如下的内容:

Contract address:

复制代码
0x9A676e781A523b5d0C0e43731313A708CB607508

1.23.2 向区块链发送信息

Foundry 内置了一个名为 Cast 的工具。Cast 附带了许多用于交互的命令。输入 cast --help 可了解更多相关信息。其中一个非常有用的命令是 send,它用于签名并发布交易。要查看 send 的帮助信息,可输入 cast send --help

要使用 send,我们需要一个函数签名和一些参数。

请在终端中调用以下命令:

**注意:**下方请使用你从终端复制粘贴的地址,该地址可能与我的部署地址不同。

复制代码
# 注意:0x9A676e781A523b5d0C0e43731313A708CB607508 为智能合约地址。
cast send 0x9A676e781A523b5d0C0e43731313A708CB607508 "store(uint256)" 999 --rpc-url $RPC_URL --private-key $PRIVATE_KEY

执行成功后出现如下的内容:

我们刚才做了什么?

让我们分解一下:

  • cast send 是我们用来签名并发布交易的命令;

  • 0x9A676e781A523b5d0C0e43731313A708CB607508 或其他地址是我们的 cast send 的目标,也就是我们正在交互的合约;

  • "store(uint256)" 是我们调用的函数的签名;

  • 1337 是我们传递给 store 函数的数字。正如我们在函数签名中所见,我们需要提供一个 uint256 类型的输入。显然,你可以提供任意你想要的数字,只要它符合 uint256 的范围;

  • 你已经知道 --rpc-url $RPC_URL --private-key $PRIVATE_KEY 是什么了------这是我们发送交易的目标地址以及用于签名的私钥。

1.23.3 从区块链读取信息

cast 还提供了一种便捷的方式来读取存储在区块链上的信息。在终端中输入 cast call --help 可以了解更多信息。它的工作方式与 send 类似,你需要提供一个函数签名和一些参数。不同之处在于,你只是查看存储内容,而不是修改它。

请在终端中调用以下命令:

复制代码
# 注意:这个位置的是合约地址,不是部署的账户地址
cast call 0x9A676e781A523b5d0C0e43731313A708CB607508 "retrieve()"

我们收到以下回复:

复制代码
0x00000000000000000000000000000000000000000000000000000000000003e7

这代表一个十六进制值。在之前的课程中,我们学习了如何将其转换为普通数字。

请在终端中输入以下命令:

复制代码
cast --to-base 0x00000000000000000000000000000000000000000000000000000000000003e7 dec

惊喜连连,返回的结果是 999。

我建议你多尝试一下,发送几笔不同数值的交易,然后再从区块链上把它们读取出来。

太棒了!我们学到了非常宝贵的一课。这个操作你以后会用上无数次。

接下来:在 Sepolia 测试网上部署智能合约

1.24 在测试网(Sepolia)上部署智能合约

~~~~~~注意:此步骤需要测试币~~~~~~~

1.24.1 使用 Foundry 和 Alchemy 将合约部署到测试网或主网

大家好!你是否好奇过自己的合约在测试网或主网上会是什么样子?如果答案是肯定的,那就请系好安全带,因为这篇博文将详细介绍这一过程!我们将逐步讲解如何更新环境变量(.env)文件,使其适用于真实的测试网。

显然,我们需要一个真正的测试网来部署到真实网络。但我们信赖的 MetaMask 内置了 Infura 连接,这些连接并不兼容。为什么呢?因为它们是为 MetaMask 量身定制的。因此,我们需要自己的远程过程调用(RPC)URL。

1.24.2 为测试网创建我们自己的 RPC URL

要创建一个 RPC URL,我们可以运行自己的区块链节点,但说实话------很多人并不想走这条路。因此,我们可以利用节点即服务(NaaS)应用来加快这一过程。

Alchemy 是一个不错的选择------它是一个免费的 NaaS 平台,我们可以通过它将交易发送出去。这部分内容位于 Foundry 完整课程仓库中的"部署到测试网或主网"章节。

要访问 Alchemy 平台,我们只需点击上述功能即可。进入平台后,我们进行注册(本演示中我使用了 Google 登录)。

下一步,在 Alchemy 用户界面中创建一个新应用。我将应用命名为"Sepolia Testing",由于我们的链将是基于以太坊的,因此描述保持不变。

我们可以先跳过高级功能,直接完成应用的创建。现在我们拥有了节点所需的应用详细信息,包括调用频率及其他相关数据。此外,点击"查看密钥"后,我们还会获得一个新的 HTTPS 端点,其使用方法与我们的 Ganache 或 MetaMask 端点完全相同。

1.24.3 修改我们的私钥

接下来,我们来处理一下私钥的问题。我们之前使用的 Ganache 私钥已经不再适用了------它里面既没有真实资金,也没有任何测试网 ETH。

我们的解决方案是使用 MetaMask 中的一个私钥。为此,我们在 MetaMask 中切换回 Sepolia 测试网,选择一个有资金的账户,点击账户详情,然后导出私钥。请记住,切勿泄露你的真实私钥!

输入密码确认后,复制该私钥,并在 env 文件中将其添加到对应的行(注意去掉表示注释的井号或英镑符号)。

执行交易

有了 Sepolia 的 RPC URL 和从 MetaMask 获取的私钥,现在执行交易将变得异常简单。

复制代码
source .env
forge script script/deploySimpleStorage.s.sol --rpc-url=$Sepolia_RPC_URL --private-key=$PRIVATE_KEY --broadcast

这条命令会将我们的合约部署到测试网,我们可以在 Alchemy 的控制面板上监控这笔交易。

我们很快就会发现,我们的合约 Simple Storage 已经部署到了 Sepolia 链上。我们可以获取交易哈希,并将其输入 Sepolia Etherscan 浏览器,以确认交易已成功完成。

刷新 Alchemy 控制面板后,我们会验证已发送的请求,并追踪到将交易发送至区块链的那笔 ETH 发送原始交易。

以上就是我们如何利用 Foundry 和 Alchemy 将合约部署到真实测试网的过程!

下一步,我们将探索如何加入真实世界的组件。敬请期待!

**此网址查询转账记录:**https://sepolia.etherscan.io/

1.25 测试

1.26 在Etherscan上验证智能合约

1.26.1 在区块浏览器上手动验证智能合约

所以......我们刚刚在 Sepolia 上部署了智能合约,让我们来看看吧!

**注意:**本节课演示的是在 Etherscan(使用最广泛的区块浏览器)上进行验证。该流程在 Blockscout 和其他浏览器上几乎完全相同。稍后,我们将学习如何使用 Foundry 通过编程方式进行验证,这种方式支持多种浏览器。

我们点击这里,进入 Contract 标签页,然后找到以下内容:

这段字节码看起来非常糟糕。我们需要采取一些措施来提高其可读性(目前几乎毫无可读性可言)。

Etherscan 通过以下消息提示我们采取行动:你是合约创建者吗?今天就验证并发布你的合约源代码吧!

因此,让我们点击 VerifyPublish

合约地址已预先填充,如果没有,请从终端粘贴过来。

选择 Solidity(单文件),因为我们使用的是 Solidity 并且只有一个文件。

选择你的编译器版本。我的合约使用的是 solidity 0.8.19。

我们使用的许可证类型是 MIT。

在下一页,粘贴你的 Solidity 合约。在 Optimization 选项中选择 Yes,其他选项保持默认。

完成验证流程。如果你看到这条消息:

复制代码
Successfully generated Bytecode and ABI for Contract Address [0x1093560Fe9029c4fB9044AbF2fC94288970D98Db]

你做对了!

现在你可以访问**Read Contract** 和**Write Contract**了。这样你就能通过区块浏览器直接与你的合约进行交互。

恭喜你!你刚刚学会了如何以手动方式验证智能合约。虽然这不是最理想的方法,但将来我们会教你如何通过编程方式来进行验证。

1.27 项目收尾工作

1.27.1 清理项目

在这个项目中,我们已经涉猎了广泛的内容。我们学习了如何编写第一个 Solidity 合约,如何将其部署到测试网络,以及如何使用 Forge 与之交互。在进入更复杂的项目之前,让我们花点时间清理一下,确保我们的项目结构井然有序。

1.27.2 格式化

任何项目的一个重要方面就是格式的一致性。我们一直在使用 VS Code 的自动格式化工具来帮助实现这一点,但重要的是要确保项目中的其他协作者也遵循相同的格式化规则。

Forge 内置了一个格式化命令,我们可以用它来确保整个项目的格式一致。我们可以在终端中运行以下命令:

复制代码
forge fmt

此命令将根据 Forge 的默认样式自动格式化我们所

复制代码
# SimpleStorage

This is a simple Solidity contract that stores a single uint256 value.

## Getting Started

1. Clone this repository.
2. Install Forge using the instructions found at [https://github.com/foundry-rs/foundry](https://github.com/foundry-rs/foundry).
3. Run the following command to compile the contract:

```bash
forge build
```

4. Run the following command to deploy the contract to a test network:

```bash
forge create
```

5. Interact with the contract using Forge's interactive console.

```bash
forge console
```

## Contributing

We welcome contributions to this project. If you're interested in contributing, please open an issue or submit a pull request. 
```
We can preview our `README.md` file in VS Code by going to the `View` menu and selecting `Open Preview to the Side`. This will open a new window showing what the `README.md` file will look like when it's rendered on GitHub.

### Using AI for Markdown Formatting

If you find that formatting Markdown is a bit tedious, you can use an AI tool like ChatGPT to help you out. Just copy and paste the text you want to format into ChatGPT and ask it to format it in Markdown. It will do a pretty good job of converting your plain text into Markdown, and you can then review and edit it as needed.

有的 Solidity 文件。

README.md

任何项目中另一个重要的文件是 README.md 文件。该文件作为指南,供任何想了解你的项目、如何使用它或如何为其做出贡献的人查阅。

README.md 文件使用 Markdown 编写,这是一种易于阅读和编写的轻量级标记语言。

以下是你可能希望在 README.md 文件中包含的内容示例:

复制代码

1.28 Foundry ZKsync

在本课中,我们将探索在 ZKsync 上进行 Layer 2 部署。与以太坊相比,这涉及一种不同的编译方式,这种差异源于 ZKsync 使用了独特的操作码。虽然 Solidity 代码在两个平台上的行为相似,但 Foundry 在 /out 文件夹中生成的底层输出将无法与 ZKsync 虚拟机完全兼容。

1.28.1 Foundry ZKsync

要开始使用 ZKsync,我们将按照以下三个步骤操作:

(1)安装 foundry-zksync

(2)使用 --zksync 标志编译 Solidity 合约

(3)重新安装原版 Vanilla Foundry

⚠️ 重要提示: 安装 foundry-zksync 将会覆盖任何现有的 Foundry 二进制文件,例如 forgecast

本课程的 GitHub 资源中包含指向 Foundry ZKsync 仓库的链接。foundry-zksync 是 Foundry 的一个分支,专门为 ZKsync 环境定制。该仓库包含了快速安装说明,帮助你设置该工具。

  • 首先,在与你的 Foundry 项目不同的目录中克隆 Foundry ZKsync 仓库。使用 git clone 命令将该仓库克隆到本地计算机上。

  • 克隆完成后,进入所创建的 Foundry ZKsync 目录,并运行安装命令:

    ./install-foundry-zksync

此命令需要在类 Unix 环境(例如 Windows 上的 WSL,或者 Mac 或 Linux 系统)中运行。执行命令后,通过 forge --version 检查版本以验证安装。若显示不同的版本号,则表明 Foundry ZKsync 已成功安装。

  • 为了保持环境的灵活性,你可以通过运行 foundryup-zksync 来切换到 Foundry ZKsync。使用之后,建议再运行 foundryup 命令切换回原版 Foundry。这会移除 ZKsync 特有的标志和设置,使你能够根据需要轻松地在 Foundry ZKsync 与原版 Foundry 之间切换。

1.29 编译 Foundry ZKsync

之前,当我们运行 forge build 命令时,它会在项目根目录下生成一个 /out 文件夹。该文件夹包含了所有与以太坊虚拟机(EVM)和原版 Foundry 相关的编译细节。而要为 ZKsync 链进行编译,我们使用 forge build --zksync 命令。该命令会在项目根目录下创建一个名为 /zkout 的新文件夹,其中包含了与 ZKsync Era 虚拟机兼容的所有编译代码。

如果我们需要恢复使用原版 Foundry 以在 EVM 上进行部署,只需运行 foundryup 命令,然后使用 forge build,这样便会构建一个标准的 Foundry 项目。除非另有说明,否则我们应继续使用此方法。

1.30 Anvil ZKsync已更新

1.30.1 Anvil ZKSync 更新

在本课中,我们将学习如何部署到 ZKSync 本地节点。它类似于 Anvil,但专为 ZKSync 设计。我们将介绍 ZKSync 的最新更新,这些更新使得仅需一条命令即可完成部署,无需额外安装。要利用这一简化流程,拥有最新版本的 Foundry-ZKSync 非常重要。

我们希望将合约部署到 ZKSync 环境中的原因,是为了确保我们的合约不仅能在以太坊环境中运行,也能在 ZKSync 上平稳运行。

让我们重新查看一下 Foundry ZKSync 仓库。我们需要确保使用的是最新版本的 Foundry-ZKSync。

如果你安装的是旧版本的 foundryup-zksync,可能需要重新安装才能下载 Anvil-ZKSync。

运行以下命令进行安装:

复制代码
curl -L https://raw.githubusercontent.com/matter-labs/foundry-zksync/main/install-foundry-zksync | bash

要启动本地运行的 ZKSync 节点,您可以运行:

复制代码
anvil-zksync

随后你会看到与 Anvil 类似的内容:一些可供使用的富账户及其对应的私钥,以及其他信息,例如第一层和第二层 Gas 价格,以及你所监听的端口------如果你想要向你的 Anvil ZKSync 节点广播任何交易,这个端口就是你需要的 RPC URL。

1.31 ZKsync本地节点

~~~~~使用上一节的内容也可以实现本地节点设置~~~~~

**重要提示:**本课为选学内容。如果你在安装或理解所需工具时遇到困难,可以直接进入下一节,继续使用 Anvil 在本地测试智能合约。

在前面的课程中,我们学习了如何使用 forge createforge script 命令在本地 Anvil 链上部署智能合约。在本课中,我们将设置并运行一个 ZKsync 本地环境。

1.31.1 本地节点设置

要在 ZKsync 本地链上进行部署,你需要额外的工具:Docker、Node.js 以及 zksync-cli。

(1)Docker: 启动 Docker 守护进程。在 Mac OS 上,可以通过 Docker 应用程序界面启动;在 Linux 上,可以使用 sudo systemctl start docker 命令启动,用 sudo systemctl stop docker 来管理 Docker 的生命周期。使用 docker --versiondocker ps 命令验证安装是否成功。

(2)Node.js 和 npm: 安装 Node.js 和 npm。请参照 Node.js 官方文档为你的操作系统安装合适的版本。使用 npm --versionnode --version 命令验证安装情况。

(3)zkSync-cli: 在 Docker 和 Node.js 安装完毕后,你可以安装 zkSync-cli 来管理本地的 ZKsync 开发环境。运行 npx zksync-cli dev config 来设置配置。选择 in-memory 节点选项以便快速启动(无持久化状态),除非你想自行探索,否则请避免选择门户网站或区块浏览器等附加选项。

要启动本地 ZKsync 节点,请运行 npx zksync-cli dev start。该命令会在 Docker 中启动一个 ZKsync 节点并在后台运行。使用 docker ps 命令验证进程是否正在运行。

注意: 如果 Docker 未运行,npx zksync-cli dev start 命令将执行失败。在尝试再次启动 ZKsync 节点前,请确保 Docker 正在运行。

1.31.2 部署

ZKsync 的部署过程与之前的部署类似。我们将使用相同的命令,但这次会附加 --zksync--legacy 标志。需要注意的是,forge script 命令在 ZKsync 中支持不佳,因此我们将改用 forge create 命令。

**总结:**设置本地 ZKsync 节点需要一些额外的工具,包括 Docker、Node.js、npm 和 zksync-cli:它们将有助于创建一个强大的 ZKsync 开发环境,并支持在 ZKsync 本地链上测试和部署智能合约。

1.32 ZKsync本地部署

在本课中,我们将把 SimpleStorage.sol 合约部署到 ZKsync 本地链上。

首先,确认我们使用的 Forge 版本是否正确。运行 forge --version 命令,确认版本号为 0.2 开头,这表明我们使用的是正确的 Foundry ZKsync 版本。

接下来,我们使用以下命令创建 SimpleStorage 合约:

复制代码
forge create src/SimpleStorage.sol:SimpleStorage --rpc_url <RPC_URL> --private_key <PRIVATE_KEY> --legacy --zksync

其中,<RPC_URL> 代表 ZKsync 节点的地址,例如 http://127.0.0.1:8011

⚠️ **重要提示:**在命令中直接包含私钥并非安全做法。

该命令指示 Foundry 定位 src/SimpleStorage.sol 文件中的 SimpleStorage 合约并进行部署。执行后,合约将编译并成功部署。输出会显示部署者地址、已部署的合约地址以及交易哈希等详细信息。

使用 --legacy 标志是部署简单合约时的推荐做法,而更复杂的代码库可能需要不同的方法。如果在部署时不使用 --legacy 标志,可能会遇到类似 failed to serialize transactionaddress to address is null 等错误,这些内容将在后续课程中介绍。

完成后,你可以关闭 Docker Desktop,并使用 foundryup 命令恢复到原版 Foundry 环境。

1.33 交易类型

在本课中,我们将探索 ZKsync 虚拟机和 EVM 生态系统中不同的交易类型。

1.33.1 /broadcast 文件夹

当部署到 ZKsync 本地节点时,会创建一个 /broadcast 文件夹,其中包含部署交易的详细信息。在该文件夹内,你会找到以特定部署链 ID 命名的子文件夹,例如 ZKsync 的 260 和 Anvil 的 31337。这些子文件夹存储了部署过程中执行的交易数据。

通过查看这些文件夹中的 run-Latest.json 文件,我们可以观察到链上每笔交易的不同交易类型。例如,Anvil 链上的交易可能被标记为 0x2 类型,而 ZKsync 链上的交易则为 0x0 类型。在 EVM 上部署智能合约时,如果不使用 --legacy 标志,默认的交易类型为 0x2;添加 --legacy 标志后,则会变为 0x0 类型。

EVM 和 ZKsync 生态系统支持多种交易类型,以适应不同的以太坊改进提案(EIP)。最初,以太坊只有一种交易类型(0x0 传统类型),但随着生态系统的发展,通过各类 EIP 引入了多种类型。后续类型包括引入了地址和密钥访问列表的类型 1,以及被称为 EIP 1559 交易的类型 2。

重要提示: 0x2 类型是当前 EVM 的默认交易类型。

此外,ZKsync 还引入了其独特的交易类型------类型 113(十六进制为 0x71),该类型可支持账户抽象等功能。

提示: forge script 命令在某些场景下可以工作,但目前尚不清楚它在哪些情况下会失败。就本课程而言,我们将假设在 ZKsync 上工作时脚本方式不可用。

资源:

结论: ZKsync 虚拟机和 EVM 生态系统支持多种交易类型,以满足不同的 EIP 需求。通过查看部署文件夹并理解诸如 --Legacy 等标志的用法,我们可以有效地区分这些交易类型。

1.34 为什么选择L2

1.34.1 引言

在前面的课程中,我们已部署到 Sepolia 测试网,并开始接触 Layer 2 解决方案 ZKsync。部署到 Sepolia 可以模拟部署到以太坊主网的过程,有助于全面了解 Layer 1 的部署情况。但需要注意的是,目前大多数项目更倾向于部署到 Layer 2 解决方案,而不是直接部署到以太坊主网,这是由于直接部署的成本较高。

1.34.2 Gas 用量

当部署到 ZKsync 本地节点时,会生成一个 /broadcast 文件夹,其中包含大量详细的部署交易信息。例如,在我们的 run-Latest.json 文件中,可以看到 gasUsed 的值,我们可以通过输入 cast to base 0x5747A dec 将这个十六进制数 0x5747A 转换为十进制。通过这种转换,我们可以估算出在以太坊主网上的部署成本。通过查看 Etherscan 上的最新 Gas 价格,我们可以使用以下公式计算总成本:

复制代码
Total Cost = Gas Used * Gas Price

我们可以在 Sepolia Etherscan 上的部署交易中,于"交易费"部分查看这笔总费用。在本例中,

357,498 个 Gas 消耗将花费 0.000279288255846978 ETH,按当前汇率约合 7 美元。

即便像 SimpleStorage 这样极简的合约,部署到以太坊主网也可能非常昂贵。而对于包含数千行代码的大型合约,部署费用甚至可达数千美元。正因为如此,许多开发者更倾向于将合约部署到 ZKsync 这类 Layer 2 解决方案上------它们能提供与以太坊同等的安全性,但成本却低得多。

1.34.3 部署到 ZKsync Sepolia

部署到 ZKsync Sepolia 与部署到 ZKsync 本地节点类似。你可以通过 Alchemy 创建一个基于 ZKsepolia 网络的新应用,来获取 ZKsync Sepolia 的 RPC URL。然后,继续将 ZKSYNC_RPC_URL 添加到你的 .env 配置文件中。

注意: 要了解 Layer 2 解决方案的成本优势,请访问 L2Fees.info,对比在以太坊和 ZKsync Era 上发送一笔交易时巨大的成本差异。

1.35 炼金术导论

1.35.1 Alchemy:去中心化应用开发的变革者

区块链行业的创新已经取得了长足的进步,强大的工具不断进入生态系统,为开发者提供支持并提升其工作效率。Alchemy 就是这些工具之一。今天,我们邀请了 Alchemy 的开发者体验负责人 Vito 来为我们介绍这个平台、它的功能,以及如何利用它来成倍提高你的生产力。

1.35.2 什么是 Alchemy?

Alchemy 是一个配备了 API、SDK 和库的平台,旨在改善你在 Web3 项目开发中的体验。你可以将 Alchemy 视为 Web3 领域的 AWS。它既是一个节点提供商,也是一个开发者工具平台,广泛应用于数千个 Web3 和 Web2 应用中,其中包括 Adobe、Shopify 和 Stripe 等大型 Web2 企业。

像 Alchemy 这类平台之所以必要,是因为作为开发者,你通常不需要操心运行代码的服务器,也不必为应用开发部署和集成流程。这些事情你通常会交给 AWS、Azure 和 Google Cloud 等服务来处理------而 Alchemy 所做的正是同样的事,只不过它是为 Web3 而生。

1.35.3 Alchemy 是如何工作的?

Alchemy 通过多种功能的结合来提升你的开发者体验。该平台的核心组件是 Supernode(超级节点),这是一个专有的区块链引擎,在你的节点之上起到负载均衡的作用。

正如其名,Supernode 确保来自区块链的数据始终保持最新且随时可用。以 Supernode 为基础,Alchemy 构建了 Enhanced APIs(增强型 API)------这是一组 API,让从区块链获取数据变得轻而易举。

简而言之,Alchemy Supernode 位于其生态系统的核心,为增强型 API 和监控工具等功能提供支持,同时兼容多条区块链。

接下来是如何在 Alchemy 上创建新账户并充分利用该平台的分步指南:

1.35.4 在 Alchemy 上创建新账户

在 Alchemy 上创建账户不仅简单,而且完全免费。你还可以通过该平台慷慨的高级套餐免费扩展你的应用规模。

步骤 1:访问 Alchemy.com

前往 Alchemy.com 并创建一个新账户。

步骤 2:创建一个新应用

登录后,创建一个新应用。

接着,为你的应用命名并填写描述。然后,选择一个链和网络。Alchemy 目前支持大多数与 EVM 兼容的链,包括:

  • Ethereum

  • Polygon PoS

  • Polygon zkEVM

  • Optimism

  • Arbitrum

  • Solana(非 EVM 链)

1.35.5 应用专属仪表板

一旦你的应用启动并运行,你就可以访问应用专属仪表板。该仪表板提供了关于应用和基础设施健康状况的关键信息,例如延迟、计算单元和交易成功率,这些对于调试和发现问题非常有价值。

如果你发现交易成功率较低,可以前往"最近无效请求"标签页。这里会列出所有失败的请求及其失败原因,方便你进行调试和修复问题。

1.35.6 内存池观察工具

Alchemy 提供的另一个强大工具是内存池观察工具。你可以将其想象为以太坊的内存池,所有待处理的交易都在其中等待验证或被挖矿打包。

内存池观察工具提供了关于你交易的详细信息,例如:

  • 交易状态(已挖矿、待处理、已丢弃、已替换)

  • Gas 消耗量

  • 验证耗时

  • 交易金额

  • 发送方和接收方地址

这种详细的交易跟踪功能让你能更好地理解每一笔交易,并极大地帮助调试与单笔交易相关的特定问题。

1.35.7 总结

总而言之,Alchemy 是一个革命性的平台,它带来了大量工具来助力你的 Web3 开发体验。从 Supernode 到增强型 API,再到关键的故障排查工具,Alchemy 无疑是在去中心化应用领域的一个颠覆者。

"Alchemy 可以成为任何区块链开发者的强大资产,在原本复杂的 Web3 环境中提供简化的体验。"------Vito,Alchemy 开发者体验负责人。

Vito 建议你查阅 Alchemy 的文档,以进一步探索该平台及其 API、SDK、库和工具。同时,别忘了在 Twitter 上关注他们:@AlchemyPlatform 和 @AlchemyLearn。如果你想直接与 Vito 联系,欢迎在 Twitter 上通过 @VitoStack 与他沟通。

Alchemy 正在革新区块链开发的格局,让所有参与者都能更便捷、更高效地构建应用。祝你在 Alchemy 上开发愉快!

1.36 总结一下,恭喜

1.36.1 庆祝 Foundry 里程碑:我们近期项目的完整回顾

此刻,你应该能感受到一股浓浓的成就感。在 Foundry 中完成一整个项目绝非易事。如此坚韧不拔的努力,值得热烈祝贺。本文旨在快速而全面地回顾我们在项目中学到的所有内容,并为下一阶段做好准备。从此刻起,请放心,我们将继续提升 Foundry 技能,在 GitHub 上推进新项目,并熟悉更高级的工具。

1.36.2 快速回顾:项目中的关键收获

首先,我们经历了使用 Forge 和 Knit 创建新 Foundry 项目的全过程。这些关键工具为我们搭建了一个结构化的专业环境,配备了各类文件夹,使工作井然有序。

我们不仅学习了 Foundry 的基本命令,还掌握了它们的具体功能,例如:

  • Cast:与已部署的合约进行交互。

  • Forge:编译合约并与我们的合约进行交互。

  • Anvil:部署本地区块链,类似于我们使用过的另一个工具 Ganache。

我们学习过程中的一个关键点,是理解了通过 MetaMask 发送交易,本质上等同于向特定的 RPC URL 发起 HTTP POST 请求。类似的 RPC URL 可以从像 Alchemy 这样的节点即服务(NaaS)提供商处获取,并用于直接从我们的 Foundry 项目中发送交易。

我们掌握了在 Foundry 中编译代码以及编写 Solidity 脚本以供后续部署的实用知识。同时,我们也认识到确保私钥安全的重要性。因此,在本课程中,我们将一直使用 .env 文件。但需要提醒的是,在处理真实资金时,将私钥以明文形式存储是不可取的。

1.36.3 理解区块链上的合约部署与交互

我们深入探讨了如何自动化地将合约部署到区块链上。部署完成后,我们使用 cast 关键字和 send 命令与合约进行交互(发送交易),随后又通过 cast call 命令从这些合约中读取数据。

此外,我们还掌握了如何使用 forge format 命令自动格式化合约。同时,我们也学习了在区块链上验证合约的手动方法,虽然过程辛苦,但收获颇丰。

复制代码
forge format my_contract.sol

1.36.4 展望未来

拥有了这些 Web 开发工具库,你表现得非常出色------是的,你完全有理由感到无比自豪。请记住,即使是像安装 Vs codeFoundry 这样的小事也可能困难重重,因此,你做得非常棒。

稍作喘息吧。请记住,休息能提升效率。下次再见,愿你继续在你所写的每一行代码中追求卓越!

1.37 测试

相关推荐
反向跟单策略2 小时前
期货反向跟单:跨合约跟单的意义及操作方法
大数据·人工智能·学习·数据分析·区块链
白沙染赤2 小时前
《区块链技术与应用》--笔记【4-6】
笔记·区块链
EutoCool2 小时前
Web3:在你的项目中如何使用Hardhat框架
web3
技术路线图3 小时前
告别存量厮杀!深度解构 LV纪元:Web3 的终极价值引擎
web3
迷藏4944 小时前
**标题:发散创新:基于IPFS的去中心化文件存储与智能合约交互实战*
java·python·去中心化·智能合约·交互
好家伙VCC4 小时前
# 发散创新:基于状态通道的以太坊智能合约高效交互实践在区块链应用开发中,**交易
java·python·区块链·智能合约
kida_yuan15 小时前
【以太来袭】6. Besu 的 API 与调试体系
运维·区块链
2501_9216494919 小时前
期货 Tick 级数据与基金净值历史数据 API 接口详解
开发语言·后端·python·websocket·金融·区块链
三秋树1 天前
Foundry Fuzz 测试完全指南:从入门到生产级智能合约安全测试
区块链