ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

深入 SmartBugs 源码:从 CLI 参数到 Docker 任务调度的执行全流程

2026/8/16 15:46:55 拓冰建站 浏览量
深入 SmartBugs 源码:从 CLI 参数到 Docker 任务调度的执行全流程

深入 SmartBugs 源码:从 CLI 参数到 Docker 任务调度的执行全流程

【免费下载链接】smartbugsSmartBugs: A Framework to Analyze Ethereum Smart Contracts项目地址: https://gitcode.com/gh_mirrors/smar/smartbugs

SmartBugs 是一个开源的以太坊智能合约安全分析框架,能够统一调度 Mythril、Slither、Oyente 等 30+ 分析工具。本文带你深入 SmartBugs 源码,完整梳理从命令行参数解析、配置合并、任务组装到 Docker 容器并行调度的执行全流程,帮助新手快速看懂框架内部运作机制。

SmartBugs 执行全流程:一张图看懂整体架构

SmartBugs 的源码核心位于sb/包中,整个执行链路可以浓缩为 6 个关键阶段:

┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ CLI 入口 │──▶│ 配置合并 │──▶│ 文件收集 │──▶│ 任务组装 │──▶│ 并行调度 │──▶│ 结果解析 │ │ cli.py │ │settings │ │smartbugs│ │smartbugs│ │analysis │ │parsing │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ ▼ ▼ Docker 执行 结果文件 docker.py result.*

每个阶段各司其职:sb/cli.py负责解析参数,sb/settings.py负责配置合并,sb/smartbugs.py负责文件收集与任务组装,sb/analysis.py负责多进程调度,sb/docker.py负责容器执行,sb/parsing.py负责结果标准化。

第一步:SmartBugs 入口与 CLI 参数解析

程序从哪里开始执行

SmartBugs 的入口非常简洁,无论是运行python -m sb还是直接执行smartbugs命令,最终都会调用sb/cli.py中的main()函数:

# sb/__main__.py import sb.cli if __name__ == "__main__": sb.cli.main()

真正干活的是sb/cli.py中的cli_args()函数,它使用 Python 标准库argparse构建命令行解析器,并把参数划分为四个分组,逻辑非常清晰。

四大参数分组速览

  • 输入选项(input)-t/--tools指定分析工具、-f/--files指定合约文件(支持 glob 通配符和DIR:前缀)、-c/--configuration指定配置文件、--main只分析同名合约、--runtime分析部署后的字节码而非部署代码
  • 执行选项(execution)--processes设置并行进程数、--timeout设置每个任务的超时秒数、--cpu-quota--mem-limit限制 Docker 容器资源、--continue-on-errors出错后继续执行
  • 输出选项(output)--runid设置运行标识、--results指定结果目录、--json输出解析后的 JSON、--sarif额外输出 SARIF 格式、--quiet静默模式
  • 信息选项(information)-v/--version显示版本、--debug开启调试日志

值得注意的是,cli_args()中凡是值为None的参数都会被丢弃,这正是"命令行参数优先级最高"这一设计的实现基础。

第二步:配置合并的优先级顺序与模板展开机制

三级配置的合并顺序

SmartBugs 的配置采用"低优先级在前、高优先级在后"的覆盖式合并,在sb/cli.pycli()函数中实现:

  1. 站点级配置site_cfg.yaml(项目根目录)
  2. 用户级配置~/.smartbugs/cfg.yaml
  3. 命令行-c指定的配置文件
  4. 命令行直接传入的参数(优先级最高)

freeze() 冻结与模板变量展开

配置合并完成后,sb/smartbugs.pymain()会调用settings.freeze()把所有模板变量一次性展开。默认的runid${YEAR}${MONTH}${DAY}_${HOUR}${MIN},会自动替换成类似20260815_0840的时间戳;结果目录默认模板为results/${TOOL}/${RUNID}/${FILENAME},其中的$TOOL$FILENAME等变量则留到生成每个任务时再逐个替换,相关实现见sb/settings.pyresultdir()方法。

第三步:工具加载与三种分析模式匹配

SmartBugs 之所以能统一调度众多工具,靠的是sb/tools.pyload()函数。每个工具在tools/<工具名>/config.yaml中声明自己的配置,例如 Mythril 的配置就同时声明了soliditybytecoderuntime三种模式。

alias 别名机制

有些工具目录只是别名,比如tools/slither/config.yaml里只有一个alias: [slither-0.11.3]load()发现alias字段后会自动递归加载指向的真实工具配置,这就是为什么你可以在命令行中写slither而无需关心具体版本。

三种模式与文件类型的对应关系

  • solidity模式:分析.sol源码文件
  • bytecode模式:分析.hex部署字节码
  • runtime模式:分析.rt.hex运行时字节码(或使用--runtime参数)

另外,工具配置中的commandentrypointstring.Template模板,执行时会把$FILENAME$TIMEOUT$BIN$MAIN等变量替换为实际值,见sb/tools.py中的command()entrypoint()方法。

第四步:文件收集与任务组装的完整过程

collect_files:匹配合约文件

sb/smartbugs.pycollect_files()glob递归匹配文件模式,只接受.sol.hex后缀,还支持.sbd清单文件——里面每一行是一个文件路径,可以批量列出待分析合约。

collect_tasks:文件 × 工具 = 任务

任务组装是框架的核心逻辑,简单说就是"每个文件 × 每个匹配模式的分析工具 = 一个任务":

  • solc 版本匹配:对于.sol文件,先通过sb/solidity.py提取 pragma 版本约束,再用sb/semantic_version.py匹配可用的编译器版本;匹配不到会直接报错
  • 结果目录去重:多个任务可能生成相同的结果目录,disambiguate()会自动追加_2_3后缀解决冲突
  • Docker 镜像预加载ensure_tool_is_loaded()会检查镜像是否已存在,不存在则先docker pull

第五步:多进程并行调度的核心实现

任务队列与工作进程

sb/analysis.pyrun()是调度中枢,采用multiprocessingspawn模式(保证 Linux 和 macOS 行为一致):

  1. 把所有任务随机打乱后放入任务队列,队尾放入 N 个None哨兵
  2. 启动 N 个analyser工作进程(N 即--processes参数)
  3. 工作进程不断从队列取任务执行,遇到None哨兵即退出

进度统计与 ETC 预估

框架还维护了tasks_startedtasks_completedtime_completed三个共享计数器,post_analysis()根据"已用时间 ÷ 已完成任务 × 剩余任务 ÷ 进程数"实时估算剩余完成时间(ETC),让你在跑大批量任务时心里有数。

第六步:Docker 容器中的任务执行细节

临时目录挂载与命令组装

sb/docker.pyexecute()负责在容器内运行分析工具,细节非常讲究:

  • 创建临时目录,把合约文件复制进去(字节码模式还会做0x前缀清洗)
  • 将工具脚本目录bin/和 solc 编译器一并复制到临时目录
  • 临时目录以只读/读写方式挂载到容器的/sb路径
  • 默认禁用容器网络(network: none),避免分析工具意外访问外网

超时控制与三连重试

容器运行后调用container.wait(timeout=...)实现超时控制,超时则强制stop。由于 Docker 偶发连接错误,sb/analysis.pyexecute()还会在失败后等待 3~8 分钟再重试,最多重试 3 次。结束后容器会被killremove清理干净,不留垃圾进程。

第七步:结果解析、输出与常见参数速查

动态加载 parser 解析结果

分析完成后,sb/parsing.py会按工具动态加载对应的tools/<工具>/parser.py,把工具的原始输出(result.logresult.tar)解析成统一的findings / infos / errors / fails四类结果;开启--sarif时还会通过sb/sarif.py额外生成result.sarif文件,方便接入 CI 安全扫描流水线。

结果文件清单

每个任务的结果目录下最终会生成:result.log(工具日志)、result.tar(工具原始输出)、result.json(解析结果)、result.sarif(可选)、smartbugs.json(任务元数据)。

常用命令速查表

使用场景推荐命令
单工具分析smartbugs -t mythril -f samples/0.8.24/SimpleDAO.sol
多工具并行smartbugs -t mythril slither oyente -f samples/0.8.24/*.sol
控制并行度追加--processes 4 --timeout 600
输出解析结果追加--json--sarif
覆盖重跑追加--overwrite

总结:SmartBugs 源码给我们的启发

回顾整个执行全流程,SmartBugs 源码的设计有三点很值得学习:插件化——新增一个分析工具只需在tools/下放一个config.yamlparser.py配置分层——站点、用户、命令行三级配置合并思路清晰;容器化隔离——所有分析工具都在 Docker 中运行,既保证了环境一致性,又通过超时和资源限制保护了宿主机。

如果你想亲手跑一遍源码,可以执行git clone https://gitcode.com/gh_mirrors/smar/smartbugs获取项目,然后按照doc/installation.md安装依赖,再对照本文的流程一步步打断点观察,相信你对智能合约安全分析框架的理解会再上一个台阶。

【免费下载链接】smartbugsSmartBugs: A Framework to Analyze Ethereum Smart Contracts项目地址: https://gitcode.com/gh_mirrors/smar/smartbugs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考