Solidity 是面向以太坊虚拟机(EVM,Ethereum Virtual Machine——以太坊上运行智能合约的执行环境)的高级编程语言,专为编写智能合约而设计。智能合约是部署在区块链上、按预设逻辑自动执行的程序,一旦部署便不可篡改。Solidity 提供类型系统、继承、库和自定义结构体等特性,支持开发者构建代币、去中心化金融(DeFi,Decentralized Finance——基于区块链的开放式金融协议)、去中心化自治组织(DAO,Decentralized Autonomous Organization——由代码规则治理的组织形式)等链上应用。本文从安装环境、编写部署第一个合约、核心语言特性、生产部署规范四个层面展开,帮助读者快速上手并规避常见坑点。
对 AI 从业者而言,掌握 Solidity 意味着能直接参与链上 AI 代理、去中心化推理市场和数据资产化项目,是理解和审计 AI 与区块链交叉应用的基础能力。
目录
速览卡是工具类内容的固定首屏模块:30 秒判断「这工具是什么、能不能商用、适不适合我」。
为什么需要 Solidity:从“链上逻辑”到“可编程资产”
传统区块链脚本(如比特币 Script)只能实现有限的条件支付,无法表达复杂的业务逻辑。要实现代币发行、借贷清算、自动化做市等去中心化应用,必须有一种图灵完备的编程语言在链上运行。Solidity 正是为这一场景设计:它编译为 EVM 字节码,部署后在每个以太坊节点上执行相同计算,结果由共识机制保证一致。
Solidity 解决了三个核心问题:一是提供高层次的抽象(如 mapping、struct、事件日志),降低链上开发门槛;二是通过面向合约的安全模型(如地址类型、msg.sender 调用上下文)让开发者显式控制资产流向;三是内建 ABI(Application Binary Interface——合约函数与外部调用方的二进制接口规范)编码规则,使合约能与其他语言编写的客户端无缝交互。相较 Vyper 的极简与 Yul 的底层,Solidity 拥有最庞大的生态:OpenZeppelin 合约库、Hardhat 测试框架、Ethers.js 交互库均以其为一等公民,这意味着学习资源、审计工具和基础设施最为齐全。
安装与环境配置:4 步就绪
步骤一・安装 Node.js 运行时。 Solidity 开发通常基于 Node.js 生态(Hardhat、Foundry 等框架依赖)或 Python 工具链(Brownie)。推荐先安装 Node.js 20 LTS 及以上版本。若本机已有 Node,跳过此步。
步骤二・安装 solc 编译器。 通过 npm 全局或项目级安装 solc,它会下载对应版本的 Solidity 编译器 JS 封装。
步骤三・安装 Foundry(推荐)。 Foundry 是一套 Rust 编写的 Solidity 开发工具链,内置 solc 管理(forge install / foundryup 自动下载相匹配编译器),在 2025 年已成为主流开发选择,与 OpenZeppelin 等库的集成也最顺滑。
步骤四・验证环境。 运行以下命令,确认 solc 与 forge 均能输出版本号:
# 1. 安装 Node.js(若已装可跳过)curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bashnvm install 20 # 2. 安装 solc(npm 方式,可选)npm install -g solc # 3. 安装 Foundry 工具链(含 forge、cast、anvil)curl -L https://foundry.paradigm.xyz | bashfoundryup # 4. 验证solc --versionforge --version
快速上手:10 分钟部署第一个合约(Foundry 工作流)
最小可用流程的思路:用 Foundry 初始化项目 → 写一个存储合约 → 用 Anvil(本地模拟以太坊节点)启动测试链 → 用 Forge 编译并部署。Foundry 将编译、测试、部署整合进一个工具链,减少环境切换成本。
详细步骤:
1. 初始化项目:运行 forge init hello_solidity,进入目录后 forge build 编译示例合约,验证工具链可用。
2. 编写合约:在 src/ 下新建 Storage.sol,定义一个 uint256 状态变量,提供 set 与 get 函数——public 变量会自动生成 getter,无需手写。
3. 启动本地链:新开终端运行 anvil,它会启动一个监听 http://127.0.0.1:8545 的本地以太坊节点,并打印 10 个预置账户及私钥。
4. 部署合约:使用 forge create 指定合约文件、构造函数参数和私钥,部署成功后控制台输出合约地址。
5. 交互验证:用 cast send 调用 set 写入数值,用 cast call 读取 get 返回值。
部署成功后可看到 Deployed to: 0x... 输出。进阶技巧:在 foundry.toml 中为不同网络配置 rpc_endpoints,即可一键切换部署到 Sepolia 测试网,无需改命令。
// src/Storage.sol// SPDX-License-Identifier: MITpragma solidity ^0.8.24; contract Storage { uint256 public value; function set(uint256 _value) external { value = _value; } function get() external view returns (uint256) { return value; }}
# 编译forge build # 启动本地链(另开终端)anvil # 部署(使用 anvil 输出的默认账户私钥)forge create src/Storage.sol:Storage \ --rpc-url http://127.0.0.1:8545 \ --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478bede5efcae784d7bf4f2ff80 # 写入值(0x...为合约地址)cast send <合约地址> "set(uint256)" 42 --rpc-url http://127.0.0.1:8545 \ --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478bede5efcae784d7bf4f2ff80 # 读取值cast call <合约地址> "get()" --rpc-url http://127.0.0.1:8545
核心能力详解:5 大支柱
支柱一・变量与类型系统。Solidity 区分值类型(uint、address、bool)和引用类型(string、bytes、array、mapping)。值类型按值传递,修改副本不影响原变量;引用类型必须指定数据位置 memory(内存,函数内临时数据)、storage(持久存储)或 calldata(只读函数参数),选错位置会导致编译错误或意外的 gas 消耗(执行合约运算所需支付的以太坊费用)。mapping 是键值存储的核心设施,适合存储余额等查询频繁的状态,但不可遍历——需要遍历时须自行维护索引数组。
支柱二・函数可见性与状态可变性。每个函数必须声明可见性:public(合约内外均可调用)、external(仅外部调用,参数用 calldata 节省 gas)、internal(合约内及继承合约调用)、private(仅本合约)。同时需声明状态可变性:view 表示只读不改变链上状态,pure 表示连读取状态都不做,payable 表示函数可接收以太币。这些修饰符不仅是语法约束,更是链上安全边界——view 函数无法被攻击者用来篡改状态。
支柱三・事件与日志。事件(Event)是以太坊日志机制的 Solidity 抽象,用于在链上记录可检索的历史。每个事件附带 indexed 参数(最多 3 个),可作为索引过滤器被客户端高效查询。典型用途是 ERC-20 代币的 Transfer 事件——区块链浏览器和索引服务靠它追踪代币流转,而无需解析全部交易数据。事件不消耗存储空间(写入日志而非状态树),是比storage变量更经济的记录方式。
支柱四・继承与抽象合约。Solidity 支持多继承,通过 is 关键字实现;构造函数按 C3 线性化顺序执行。抽象合约(含有未实现函数)用于定义接口规范,接口(interface)则只声明函数签名——这是实现可插拔架构的关键:例如一个借贷合约可以只依赖 IERC20 接口,运行期再注入具体代币地址,从而解耦模块。
支柱五・错误处理与自定义错误。require 校验条件,失败即回滚整个交易并退还剩余 gas;revert 主动回滚并携带错误信息;assert 只用于检查不可能的条件(如不变式),失败表示代码存在 bug。0.8.4 起支持自定义错误(error InsufficientBalance(uint256 available);),相比字符串消息更节省 gas(可减少数百 gas 消耗),且可携带结构化参数便于前端解析。现代合约审计中,自定义错误是第一推荐做法。
生产部署与监控:从上线到运维
部署方式一・Foundry 脚本部署。生产级部署应使用 forge script 配合私钥管理,而非手动的 forge create。在 script/Deploy.s.sol 中编写部署脚本,设置 PRIVATE_KEY 与 RPC_URL 环境变量,运行 forge script script/Deploy.s.sol --broadcast --verify。--verify 自动调用 Etherscan API 提交源码验证,用户可据此核对部署字节码与源码一致性。多环境部署通过 --fork-url 指定主网或测试网的归档节点实现。
部署方式二・Hardhat 多网络管理。Hardhat 以 hardhat.config.ts 集中管理多个网络的 RPC 地址、私钥(推荐用 dotenv 加载)与 gas 策略。hardhat-deploy 插件提供可复现的部署记录(deployments/ 目录保存每次部署的地址与 abi),配合 npx hardhat verify 逐网络验证源码。Hardhat 的网络管理适合需要多人协作、多链发布(以太坊主网 + 多条 L2)的团队。
可观测性。链上合约的监控与传统服务器不同:无法直接查看日志,只能通过节点 RPC 查询。三条关键路径:一是事件日志索引,使用 Moralis 或 The Graph 子图索引 Transfer、Approval 等关键事件,推送变更到业务系统;二是交易监控,cast call 或 Ethers.js provider.on('block') 轮询最新区块,结合 txReceipt 状态判断合约调用成败;三是 gas 用量预警,集成 Tenderly 或 Defender Sentinel,设置单位操作 gas 成本阈值告警——gas 异常波动往往意味合约逻辑被非预期路径触发或遭受攻击。
<p class=“para-label“>避坑清单:</p><ul class=”dash-list”><li>编译器版本锁定:始终使用 0.8.x 已审计版本,pragma 用 ^0.8.24 可能引入未来未审计的编译器,生产环境建议固定精确版本号(=0.8.24)。</li><li>整数溢出:0.8.0 起默认溢出回滚,但 unchecked 块内的运算不检查,勿在需要安全校验的路径使用。</li><li>重入攻击:跨合约调用前先更新内部状态(检查-效果-交互模式),或使用 OpenZeppelin ReentrancyGuard 的 nonReentrant 修饰符。2022 年 Wormhole 桥攻击即因重入漏洞损失 3.26 亿美元。</li><li>随机数不可靠:block.timestamp 与 block.prevrandao(合并后替代 difficulty 的字段)均可被矿工/验证者操纵,链上抽奖须用 Chainlink VRF。</li><li>浮点数不存在:Solidity 没有 float,除运算截断为整数,处理代币价格须引入定点数精度(如 1e18 wei 精度)或库。</li><li>存储布局升级风险:使用代理升级模式时,新增状态变量必须追加在末尾,不得修改既有变量顺序,否则插槽冲突导致数据损坏。</li></ul>
| 维度 | Solidity | Vyper | Yul | Sway |
|---|---|---|---|---|
| 定位 | EVM 通用智能合约语言 | EVM 安全优先合约语言 | EVM 底层汇编语言 | FuelVM 合约语言 |
| 编排范式 | 面向对象多继承 | Python 风格、刻意限制 | 函数式汇编 | Rust 风格函数式 |
| 类型约束 | 静态类型,显式数据位置 | 静态类型,编译器强制安全 | 弱类型字节操作 | 静态类型,所有权机制 |
| 学习曲线 | 中等,需理解继承与 gas | 平缓,语法精简但功能受限 | 陡峭,接近机器码抽象 | 陡峭,需理解 FuelVM 差异 |
| 生态集成 | OpenZeppelin/Hardhat/Foundry 全生态 | OpenZeppelin 部分支持,工具链兼容 | 内嵌于 Solidity 编译产物 | 工具链新,生态建设中 |
| 生产部署 | 主网主流,审计工具链成熟 | 部分 DeFi 项目(如 Curve)采用 | 经 Solidity 间接用于优化 | Fuel 链专属,未普及 |
| License | GPL-3.0 | Apache-2.0 | GPL-3.0 | Apache-2.0 |
| 适合谁 | 绝大多数 EVM 项目 | 追求极简、强安全的团队 | EVM 底层开发者与 gas 优化 | Fuel 生态早期开发者 |
选型建议:绝大多数新项目直接选 Solidity,生态、人才储备、审计资源最完备。Vyper 适合安全敏感且逻辑简单的合约(如稳定币)。Yul 仅用于 Solidity 编译产物的 gas 优化补丁或自定义 EVM 语义,不作为主语言。Sway 仅在业务确定部署在 Fuel 链(模块化公链之一,采用 FuelVM 架构)时才考虑。
版本迭代
Solidity 从 2015 年 0.1.x 起持续演进,0.4.x(2016-2019)时期确立了 mapping、modifier 等核心语法;0.5.x(2019)大幅收紧语法与 ABI 编码规则;0.6.x/0.7.x(2020)引入 try/catch、receive 与更严格的显式转换;0.8.0(2020 年 12 月)是重大安全里程碑,默认启用算术溢出检查;0.8.19-0.8.24(2023-2024)持续优化编译产出并引入 transient storage(EIP-1153 相关)等新特性。截至 2025 年,0.8.x 是唯一正式发布线。
| 版本 | 时间 | 变化 | 提升 |
|---|---|---|---|
| 0.5.0 | 2018-11 | 语法收紧与 ABI 规范化 | 移除 `var`、`address` 拆分出 `payable`,ABI 编码规则明确 |
| 0.6.0 | 2019-12 | 抽象合约与虚函数改进 | 引入 `abstract` 关键字、`override` 说明符、`try/catch` 外部调用异常处理 |
| 0.7.0 | 2020-07 | 状态变量与 ABI 编码微调 | 函数状态可变性默认收紧,`receive` 函数替代 `fallback` 处理纯转账 |
| 0.8.0 | 2020-12 | 默认安全检查 | 算术溢出默认回滚、`unchecked` 显式逃逸;`msg.value` 与 `address.code.length` 可用 |
| 0.8.19 | 2023-02 | 编译性能与代码生成 | 引入 `--model-checker` 增强形式化验证、优化 ABI 解码 gas |
| 0.8.24 | 2024-01 | transient storage 支持 | 新增 `tstore`/`tload` 指令对应的 `transient` 存储位置(EIP-1153) |
| 基准 | 0.5.x | 0.7.x | 0.8.24 | |
|---|---|---|---|---|
| Gas 消耗(ERC-20 transfer) | 约 51000 | 约 47000 | 约 46000 | Solidity 官方 benchmark 显示的优化趋势 |
| 溢出攻击案例 | 频发 | 较少 | 默认阻止 | 0.8.0 起编译器默认插入溢出检查 |
| 形式化验证 | 不支持 | 实验支持 | 内建 model-checker | 0.8.19 后支持 CHC 引擎 |
Solidity 的迭代主线是“安全优先、gas 次优”——0.8.x 以默认溢出检查消除了历史上最大类别的漏洞(历史上 DeFi 攻击约 20% 与其相关)。选型建议:新项目一律用 0.8.24+,现有 0.7.x 项目应计划升级,0.6.x 及更老版本因编译器不包含完整安全加固已不适合新功能开发。
AI 应用场景
场景一:ERC-20 代币发行与通证经济
阶段:Token 合约开发与部署
解决的问题:传统股权或积分体系依赖中心化账本,缺乏透明度与可审计性。Solidity 编写的 ERC-20 合约将发行总量、转账规则固定在链上,任何地址的余额均可公开验证,且无法被单一方篡改。
具体案例:某 AI 数据标注平台发行治理代币,使用 OpenZeppelin ERC20 + Ownable 模板,总供应量 1 亿枚,初始分配 30% 给数据贡献者池。部署后每日自动释放奖励(结合链上任务合约),代币转账全量公开可查,社区审计成本下降约 70%,且因审计透明性,代币上线交易所时间从 6 个月缩短至 4 个月。
场景二:去中心化 AI 推理市场
阶段:支付结算与推理结果存证
解决的问题:中心化 API 无法证明“模型确为调用方所用的模型”,且支付走传统支付通道有跨境与手续费问题。Solidity 合约将推理请求、费用托管、结果哈希上链,实现“先托管后交付”的原子化交易。
具体案例:某 Web3 推理平台部署了模型路由合约,用户以 USDC 支付推理费,合约锁定资金并触发链下推理节点执行;节点回传结果哈希,合约比对后释放资金。平台上线 3 个月处理 12 万次推理交易,清算全部自动完成,结算周期从传统 3 天降至秒级,坏账率降为 0。
场景三:DAO 治理与链上投票
阶段:治理流程的自动化与防作弊
解决的问题:传统治理依赖邮件/论坛投票,无法验票且易受女巫攻击(Sybil Attack,同一人注册多身份刷票)。Solidity 治理合约将提案、投票权重(按代币持仓)、执行逻辑写为不可篡改代码,杜绝人工干预。
具体案例:某 AI 研究 DAO 使用 OpenZeppelin Governor 合约,持币者按 ERC-20 余额获取投票权重,提案通过后自动执行资金拨付。治理参与率从中心化时代的 8% 提升至 35%——每一笔国库支出均有链上提案对应,财务审计工作量减少约 80%。
常见误区
误区“Solidity 是编程语言,我用它写任何逻辑都行,包括复杂计算和数据库读写。”
正解Solidity 的运行环境是 EVM,每次状态写入都要支付 gas 且全网节点同步执行,计算成本比传统服务器高数个数量级。复杂计算、大规模数据存储(如数组遍历、字符串拼接)在链上既不经济也不现实,正确做法是把繁重计算放链下(或使用 ZK 证明链上验证),合约只保存核心状态与规则。
为何常见:初学者的心智模型是从通用编程语言迁移过来的,忽略了 EVM 的“每步操作都是计费与公开执行”这一根本约束。
误区“0.8.0 默认开启溢出检查,我不用再担心 `uint` 溢出了。”
正解默认检查覆盖大括号内的算术表达式,但 unchecked { } 块内的运算完全跳过检查;同时,真实攻击未必来自单变量溢出,而是跨函数的状态一致性——例如先取款后更新余额(重入)、allowance 与 balanceOf 不一致导致的授权漏洞。溢出检查只是最后一道防线,业务逻辑的“检查-效果-交互”顺序才是核心。
为何常见:编译器新特性容易给人“安全已自动解决”的错觉,而实际上 Solidity 文档明确将 unchecked 标记为“高级用户逃逸”。
误区“合约上线后如果发现 bug,我改一下代码再重新部署就行。”
正解已部署合约的字节码永久写入链上,无法直接修改。唯一方法是部署新合约并迁移状态与用户资产,这是高成本高风险过程(涉及地址变更、前端更新、用户资产迁移)。可升级合约(代理模式)能部分缓解,但升级权限本身是攻击面——2021 年 Poly Network 攻击即源于代理合约的 owner 被篡改。
为何常见:传统服务的 "patch & redeploy" 心智在区块链语境失效,开发者初期常忽视不可篡改性的深远影响。
误区“gas 优化是核心指标,我优先把代码写短,多用 `unchecked` 和 16 位 `uint`,看起来就很高效。”
正解gas 优化必须与安全、可读性平衡。激进优化(如 unchecked 包裹所有运算、用位运算替代清晰的分支)大幅增加审计人判断负担,是事故高发区。0.8.x 引入的默认检查使常规路径 gas 增加不到 3%,却消除了一整类漏洞。生产合约应优先正确性与可审计性,把优化集中在存储读写(storage 读比 memory 贵约 100 倍)这类“大头”。
为何常见:区块链行业对 gas 的过度宣传让新人误以为“低 gas 是好代码”的等价标准,忽略了成本与风险的非线性关系。
误区“合约里用 `require` 就能访问外部网站获取价格数据,我可以在链上直接调用价格 API。”
正解EVM 是无 IO 环境,合约无法发起 HTTP 请求,只能获取本链区块头内的有限信息(如 block.timestamp、block.prevrandao)。获取外部数据必须依赖预言机——Chainlink 数据源将价格等现实世界数据签名为链上可验证的凭证,由预言机节点写入链上。私自“模拟”价格源(比如让某个地址手动喂价)会造成单点故障,是 DeFi 常见攻击入口。
为何常见:现代编程习惯(API 无处不在)被直接投射到链上环境,而预言机的存在恰恰说明链上世界与网络世界是隔离的。
面试题
Q1. 下列哪个函数修饰符组合是合法的存储函数?
- A.
function f() external view returns (uint)← 正确答案 - B.
function f() public pure payable returns (uint) - C.
function f() private view returns (uint) - D.
function f() internal constant returns (uint)
答案:A。A 正确,view 函数不修改状态且可返回 uint。B 错误——pure 表示不读取状态,而 payable 暗示可接收以太币,逻辑矛盾但编译器允许,但 pure 函数实际上不允许读取 msg.value,此处不合法。C 中 private view 虽语法合法但 view 函数要求访问存储,私有函数不能读取合约存储变量,实际不可行。D 中 constant 是 0.4.x 旧关键字,0.5.0 后已移除。
Q2. 以下哪种方式能最有效地防止重入攻击?
- A.在函数开头调用
require(msg.sender == owner) - B.先更新内部余额状态,再执行外部转账← 正确答案
- C.使用
tx.origin验证调用来源 - D.在转账后立即清除
allowance
答案:B。B 是标准“检查-效果-交互”(CEI)模式,先更新状态再交互,重入发生时余额已被扣减而无法再次取款。A 只限制调用者并不能防重入。C 中 tx.origin 可被钓鱼合约诱导且已被 OpenZeppelin 明确反对。D 清除 allowance 只针对 ERC-20 授权,与重入无关。
Q3. 关于 Solidity 0.8.0 的变更,以下哪些描述正确?
- A.算术溢出默认抛出异常并回滚← 正确答案
- B.
unchecked块内运算不检查溢出← 正确答案 - C.
msg.value可直接用于view函数 - D.
address类型增加了code.length属性← 正确答案
答案:ABD。A 与 B 是 0.8.0 的核心内容,默认溢出检查与 unchecked 逃逸机制配套存在。D 正确,0.8.0 新增 code.length 用于判断地址是否为合约(在 0.8.10 前该字段不可用于内部调用上下文的地址)。C 错误,view 函数禁止读取 msg.value,这是 0.7.0 引入的变素。C 项实质性出错,故不选。
Q4. storage 与 memory 的区别是什么?
- A.
storage存储在合约持久状态中,memory在函数执行期间有效← 正确答案 - B.两者都在函数调用结束后自动释放
- C.
memory是静态数组,storage是动态数组 - D.
storage变量只能由owner修改
答案:A。A 正确——storage 是链上持久存储,memory 是执行期间的临时内存。B 错误,storage 不会自动释放。C 错误,两者都支持静态与动态数组,差别在于生命周期而非结构。D 错误,storage 变量可被任何具有权限修改该变量的函数调用(如 public 函数),不限于 owner。
Q5. 以下哪个不是 Solidity 的内置单位?
- A.wei
- B.gwei
- C.ether
- D.dollar← 正确答案
答案:D。wei、gwei、ether 是以太坊原生的货币单位(1 ether = 1e18 wei)。dollar 不是 Solidity 内建单位,价格单位不进入语言层,只能通过预言机获取。若使用 dollar 会直接编译错误。
Q6. 关于事件(Event)以下描述正确的是?
- A.事件数据永久存储在区块链日志中← 正确答案
- B.
indexed参数最多允许 4 个 - C.事件可以用于跨合约回调
- D.客户端可通过索引参数高效查询事件← 正确答案
答案:AD。A 正确,事件与区块一起永久记录在链上。B 错误——indexed 参数上限为 3 个,超过会编译报错。C 错误,链上无法“监听”事件,事件是事后记录的日志,不触发回调;跨合约交互需通过函数调用而非事件。D 正确,indexed 参数会被 ABI 编码为主题(topic),供索引器与浏览器高效检索。
Q7. 使用代理升级模式时,新增状态变量应满足什么条件?
- A.必须放在所有既有变量之前
- B.必须追加在存储布局末尾← 正确答案
- C.必须使用
transient存储 - D.新增变量必须比旧变量占用更多空间
答案:B。B 正确——代理模式依赖存储插槽(slot)布局映射,新增变量必须追加在末尾以保持与既有无变量插槽一致性,否则原插槽数据会被新变量覆盖/错位,造成数据损坏。A 会直接破坏既有变量映射。C 的 transient 存储与升级无关且 0.8.24 才支持。D 无此约束。
Q8. 关于 require 与 assert 的使用原则是什么?
- A.
require用于检查不可能的条件,assert用于用户输入校验 - B.
require用于用户输入校验与外部条件,assert用于内部不变式← 正确答案 - C.两者相同,可互换
- D.
assert失败会退还剩余 gas,require不会
答案:B。B 正确——require 处理可预期的失败(输入非法、余额不足、权限不足),失败时退还剩余 gas;assert 用于代码逻辑上的不可能情况(如溢出保护被绕过),失败时消耗全部 gas 并标记为 Panic 错误。D 写反了。A 将两者用途对调,错误。C 忽略了两者的 gas 行为与语义差异。
Q9. 在 Foundry 中以下哪些命令是正确的操作?
- A.
forge build编译合约← 正确答案 - B.
forge create部署合约← 正确答案 - C.
anvil启动本地测试链← 正确答案 - D.
forge testnet创建公共测试网络
答案:ABC。A、B、C 是 Foundry 工具链的真实命令。D 不存在——Foundry 不提供“创建公共测试网络”功能,公共测试网由以太坊基金会或第三方提供,Foundry 只能连接或模拟本地链(anvil)与分叉主网。forge testnet 是编造的命令。
Q10. 以下哪种方式能安全地获取链上价格数据?
- A.在合约中调用 HTTP API 获取实时价格
- B.使用
block.timestamp推算价格 - C.通过 Chainlink 预言机获取已上链的喂价← 正确答案
- D.让任意地址调用
setPrice写入价格
答案:C。C 正确——Chainlink 等预言机将现实世界价格聚合签名后上链,合约读取链上数据。A 在 EVM 中不可行,合约无 IO。B 的 block.timestamp 是时间戳,不含价格信息。D 存在单点操纵风险,非授权合约无法主动接收任意喂价(若合约自身定义该函数则形成价格源漏洞)。