入职 Web3 运维日记 · 第 14 日:铸造无形钥匙 —— OIDC 与 CI/CD 施工实录

时间:入职第 14 天,上午 10:00 天气:多云,代码审查室里的气氛有些焦灼 事件:发现开发团队使用个人电脑直连主网部署合约,并深度剖析 Web3 的“草台班子”现状

上午 10 点,智能合约开发组长在 Slack 核心群里发了一条消息:“新版 Vault (资金库) 合约本地测试完毕,10 分钟后我准备把它发到主网 (Mainnet)。”

作为一个 Web2 摸爬滚打出来的老运维,我对“发主网(生产环境)”这三个字有着天然的敬畏。我立刻端着咖啡走到他工位旁,随口问了一句:“咱们发主网的流程是啥?你用的哪个平台的流水线?”

组长头也没抬,切到了他的 VS Code 终端:“流水线?不用那么麻烦。我在我的 Mac 上直接跑 forge script script/Deploy.s.sol --rpc-url $MAINNET_RPC --broadcast 命令就行了。秒上链。”

我眼皮一跳:“那你部署用的私钥 (Private Key) 放在哪?”

他指着编辑器左侧的目录树,理直气壮地说:“写死在本地的 .env 文件里啊。里面这个地址有 5 个 ETH 当手续费,部署完剩下的还能用。你放心,我已经把 .env 加进 .gitignore 了,绝对不会传到 GitHub 上,很安全!”

我感觉血压瞬间飙升。这不叫安全,这叫“裸奔”。

但我忍住了直接拔网线的冲动。我看着他,问出了那个直击灵魂的问题: “兄弟,如果你以前在美团或者阿里,敢把生产环境数据库的 Root 密码写在你这台 Mac 的本地文本里,然后坐在星巴克连着公共 Wi-Fi 敲回车发版,你今天下午就会被安全部和 HR 架出大楼。为什么到了 Web3,你觉得这就理所当然了?

组长愣了一下,挠了挠头:“可是……大家都是这么干的啊。教程里也是这么教的。”

🕵️‍♂️ 为什么 Web2 的“死罪”,变成了 Web3 的“常态”?

我拉了把椅子坐下,跟他(也是跟我自己)彻底理清了这个荒谬现状背后的三大原因:

原因一:物理边界的消亡(公网无墙)

  • Web2 时代:生产环境的数据库藏在 VPC(虚拟私有云)深处,外面有防火墙、WAF、堡垒机。你在星巴克是物理上无法连接生产库的,除非你经过层层 VPN 认证。
  • Web3 时代:以太坊主网是 Permissionless(无许可) 的公共网络。没有任何防火墙。对区块链来说,你坐在公司内网发出的交易,和你坐在星巴克公共 Wi-Fi 下发出的交易,没有任何区别。只要你的签名对得上,节点就会处理。这种“极度开放”的网络环境,给了开发者一种“随时随地都能发版”的错觉和便利。

原因二:“极客英雄主义”的开发工具链

  • Web3 起源于极客和密码朋克文化。早期大部分项目都是两三个人的草台班子在黑客松上搞出来的。
  • 他们没有专业的 DevOps,所以早期的开发框架(Truffle, Hardhat,甚至现在的 Foundry)在设计时,默认的使用场景就是单兵作战
  • 你去翻看官方文档的“部署教程”,第一步永远是:“新建一个 .env 文件,粘贴你的 MetaMask 私钥”。工具层的设计导向,硬生生把整个行业的开发者培养出了极其糟糕的安全习惯。

原因三:身份与资产的高度绑定(Deployer = God)

  • 在 Web2,发版的账号(比如 Jenkins Service Account)和管钱的账号是分开的。
  • 但在 Web3,那个放在 .env 里的私钥,不仅是用来付 Gas 费的,它通常还会被智能合约自动识别为 Owner(超级管理员)
  • 这意味着,这把躺在 Mac 硬盘上的私钥,未来可能直接拥有铸造代币、暂停合约、甚至提取用户几亿美金的最高权限!

🛑 刺破谎言:叫停部署

听我分析完,组长的表情终于变了。但他还在辩解:“但我 Mac 上装了杀毒软件,而且我不乱点链接的。”

我直接按住了他的键盘:“停!这笔部署立刻取消。

“你的 .env 谎言到此为止。”我给他下了最后通牒。

  1. 单点故障 (SPOF):只要你的电脑中了一次钓鱼木马,那个装着 5 个 ETH 和最高权限的私钥瞬间被盗,公司直接上新闻头条。
  2. 代码投毒防不住:你从本地编译部署,我怎么向审计公司证明,你部署的机器码 (Bytecode) 就是 GitHub 上的那份源码?万一你私自在本地改了一行代码,留了个后门呢?
  3. 环境差异:你的 Node.js 版本、甚至 Mac 的 M系列芯片,都可能导致编译出来的 Hash 值和线上验证不一致。

我站起身,走向 CTO 办公室,留下一句话: “从今天起,彻底废除任何形式的本地主网部署。 下午 5 点前,我会交付一套零信任的 CI/CD 流水线。以后所有上主网的合约,必须通过机器自动化部署,私钥必须锁在硬件保险柜(KMS)里!”


🏗️ 施工第一步:在 AWS 建立“门卫大爷” (OIDC 信任策略)

我登录到 AWS IAM 控制台。我要教 AWS 认识 GitHub 这个“外来机构”,并定下死规矩。

1. 添加身份提供商 (IdP) 我先在 AWS 里添加了 GitHub 作为可信的 OpenID Connect (OIDC) 实体:

  • Provider URL: https://token.actions.githubusercontent.com
  • Audience: sts.amazonaws.com

2. 编写信任策略 (Trust Policy - 最核心的防线) 接着,我创建了一个 IAM 角色,命名为 Bybit-GitHub-Deploy-Role。这个角色就是给流水线准备的临时“工牌”。 但这块工牌不是谁都能领的,我给门卫大爷(AWS STS)写了一段极其严苛的 JSON 过滤规则:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::1234567890:oidc-provider/token.actions.githubusercontent.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" }, "StringLike": { // 【绝杀卡点】:必须是 Bybit 仓库的 main 分支! // 其他仓库、其他分支(比如 dev)来请求,直接 Access Denied! "token.actions.githubusercontent.com:sub": "repo:Bybit/smart-contracts:ref:refs/heads/main" } } } ] } 

3. 限制行为范围 (Permissions Policy) 领到工牌进门后,流水线能干啥?我只给了它两个极其可怜的权限:看公钥,和请求签名。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "kms:Sign", // 允许请求签名 "kms:GetPublicKey" // 允许获取公钥地址 ], // 只能碰这一把指定的冷钱包部署私钥,别的资源看都看不见 "Resource": "arn:aws:kms:ap-southeast-1:1234567890:key/mrk-abc123deploykey" } ] } 

📜 施工第二步:编写流水线大脑 (deployment.yml)

AWS 那边的门卫调教好了。现在我回到 GitHub 仓库,在 .github/workflows/ 目录下新建了 deployment.yml

这份 YAML 文件,就是彻底终结那个危险的 .env 文件的最终武器。我把它分成了三个严密的阶段。

name: Compliant Mainnet Deployment # 1. 触发条件:绝对禁止自动发版 on: workflow_dispatch: inputs: network: description: 'Target Network (mainnet / sepolia)' required: true default: 'mainnet' # 2. 赋予流水线申请 OIDC Token 的权限 (极其重要的一句!) permissions: id-token: write # 必须有这个,GitHub 才会生成用来骗过 AWS 门卫的 JWT 证件 contents: read jobs: # 阶段一:无状态编译 build: name: 🏗️ Compile with Foundry runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 - name: Build Smart Contracts run: forge build # 阶段二:Slither 死亡安检 (防线) security-audit: name: 🛡️ Slither Security Scan needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Run Slither Analyzer uses: crytic/[email protected] with: target: 'src/' fail-on: high # 只要查出高危漏洞(如重入攻击),立刻中断! # 阶段三:无私钥签名部署 deploy: name: 🚀 Sign & Broadcast via KMS needs: security-audit # 只有安全审计全绿,才能走到这里 runs-on: ubuntu-latest environment: production # 触发 GitHub 页面上的审批按钮 (Approve) steps: - uses: actions/checkout@v3 # 魔法时刻:向 AWS 出示 OIDC 证件,换取 15 分钟临时凭证 - name: Authenticate to AWS KMS (No Passwords!) uses: aws-actions/configure-aws-credentials@v2 with: role-to-assume: arn:aws:iam::1234567890:role/Bybit-GitHub-Deploy-Role aws-region: ap-southeast-1 # 执行部署脚本 (此时环境里已经有了 AWS 临时凭证) - name: Execute KMS Deployment run: | echo "Connecting to AWS KMS..." # 这里通常是一个封装好的 TS/Python 脚本,调用 KMS API 签名并向 RPC 发送交易 node scripts/deploy_kms.js --network ${{ github.event.inputs.network }} 

最后三步:在 KMS 内部“孕育”私钥

我们不导入私钥,我们命令 AWS KMS 的底层硬件(HSM 防弹芯片)原生生成一把私钥。它从出生的那一刻起,就被焊死在芯片里。

操作步骤如下:

  1. 选择算法: 在 AWS KMS 点击“创建密钥”。选择 非对称 (Asymmetric),用途选 签名和验证 (Sign and verify)
  2. 选择以太坊专用的“灵魂曲线”: 这一步极其关键。以太坊使用的密码学曲线叫 secp256k1。你在 AWS KMS 的下拉菜单里,必须精准地选中 ECC_SECG_P256K1。如果选错了,生成的签名以太坊根本不认。
  3. 完成创建: 点击确定。就这么简单,私钥诞生了。
第四步:发起“权力移交”交易

你需要用你原来的本地旧私钥(就是那个 .env 里的)执行一次合约调用。你可以用 Foundry 的命令行工具 cast 快速完成:

# 命令解释: # cast send [合约地址] "transferOwnership(address)" [新KMS地址] --private-key [旧私钥] --rpc-url [主网RPC] cast send 0xVaultContractAddress "transferOwnership(address)" 0xNew_KMS_Address \ --private-key $OLD_PRIVATE_KEY \ --rpc-url $MAINNET_RPC 
第五步:验证权力移交

去 Etherscan 上查看你的合约,点击 "Read Contract",查看 owner 变量。

  • 如果显示的地址已经是 0xNew_KMS_Address,那么恭喜你,移交成功!

下午 4 点,我把这段 YAML 代码推到了 main 分支。

这时候的架构已经完美了:

  1. 没有密码:无论是本地电脑还是 GitHub 仓库,都没有明文的 Access Key 或私钥。
  2. 双重锁死:开发人员想发主网,必须推代码到 main 分支;推上来之后,必须通过 Slither 的安全扫描;全绿之后,还要等我和 CTO 在网页上点击 Approve。


🚨 16:15 PM:触雷!Slither 的无情绞杀

组长点击了 Run workflow。 我们俩并排站在屏幕前,盯着 GitHub Actions 的运行日志。

  • 第一步:🏗️ Compile with Foundry。用时 12 秒,绿灯 ✅。 组长得意地说:“看吧,我本地编译没问题,云端肯定也没问题。”
  • 第二步:🛡️ Slither Security Scan。日志开始疯狂滚动。

就在这时,页面突然一闪,一个刺眼的红色叉号 (❌) 弹了出来。构建失败!流水线被强制熔断。 第三步的 🚀 Sign & Broadcast via KMS 直接变成了灰色的 Skipped(跳过)。

组长急了:“Alen,你这什么破流水线!我本地跑 forge test 测试用例明明全过了(100% Pass),怎么到你这就挂了?”

我没有说话,点开了 Slither 阶段的红色报错日志。屏幕上赫然印着几行冰冷的英文:

INFO:Detectors: High Risk Vulnerability Detected: Reentrancy Contract: Vault.sol Function: Vault.withdraw(uint256) Details: External call made before state variable update. - msg.sender.call{value: amount}("") (Vault.sol#42) - balances[msg.sender] -= amount (Vault.sol#44) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities Error: Slither found 1 High severity issues! Failing build. 

🧠 16:20 PM:为什么本地测试抓不出这个 Bug?

看到 Reentrancy(重入攻击)这个词,组长的脸色瞬间煞白。 这是以太坊历史上最臭名昭著的漏洞。当年 The DAO 就是因为这个漏洞被黑了 5000 万美金,直接导致了以太坊主网硬分叉出 ETC。

他的代码是这么写的:

function withdraw(uint256 amount) public { require(balances[msg.sender] >= amount, "Not enough balance"); // 【致命错误】:先给钱,把执行权交给了外部! (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed"); // 然后才扣减数据库里的余额 balances[msg.sender] -= amount; } 

我拍了拍他的肩膀:“兄弟,本地的单元测试(Unit Test)往往只测正常的业务逻辑。你测了存 100 块,取 50 块,余额剩 50 块,当然是绿的。 但黑客不会按套路出牌。黑客会写一个恶意合约,在收到你这笔钱的瞬间(触发 fallback 函数),再次回头调用你的 withdraw 函数。 因为你还没执行到 balances -= amount 这一步,系统认为黑客账户里还有钱,于是又给他发了一笔……无限循环,直到把你资金库里的几千万美金抽干。”

组长擦了擦头上的冷汗:“如果上午我用本地电脑直连主网部署了……明天公司可能就破产了。”

🔧 17:00 PM:修复与二次闯关

组长飞奔回工位,老老实实地重写了逻辑。 他遵循了智能合约最核心的安全铁律:CEI 模式 (Checks-Effects-Interactions)。 先把余额扣掉(Effects),再去给用户转钱(Interactions)。并且引入了 OpenZeppelin 的 nonReentrant 互斥锁。

代码重新 Push,流水线再次触发。 这次,Slither 扫描:绿灯 ✅!

🚀 17:30 PM:核按钮与完美点火 (Environment Approval)

流水线走到了最后一步:🚀 Sign & Broadcast via KMS。 但这步并没有直接运行,而是变成了黄色的等待状态 (Waiting for Review)

CTO 的手机和我电脑上的 Slack 同时响了。

🤖 GitHub Actions 提醒Compliant Mainnet Deployment 正在请求部署到 production 环境。 请管理员审核。

这是我在 YAML 里配置的最后一道防线:环境审批。 我走到 CTO 办公室,他看了一眼 Slither 的全绿报告,我们在各自的 GitHub 页面上郑重地点击了 "Approve and Deploy"

接下来,就是见证 OIDC 与 KMS 密码学魔法的时刻了。

我们在日志里清晰地看到了这一切的发生,而黑客在网线另一端只能绝望地看着:

  1. Authenticating via OIDC... Success. (拿到了只活 15 分钟的 AWS 临时凭证)
  2. Connecting to AWS KMS HSM... (连接防弹保险箱)
  3. Sending bytecode hash to KMS for signing... (把编译好的机器码送进保险箱)
  4. Received signature (v, r, s) from KMS. (印章盖好,拿到了谁也看不懂但全网都认的数字签名)
  5. Broadcasting transaction to Ethereum Mainnet...
  6. Transaction confirmed at Block #18452901! Contract Address: 0x...

部署成功。

至此,那台完成了历史使命的 GitHub 临时 Ubuntu 虚拟机,像完成了刺杀任务的特工一样,瞬间销毁,不留一丝痕迹。

Read more

2026AI大模型常问的问题以及答案【附最新的AI大模型面经】

2026AI大模型常问的问题以及答案【附最新的AI大模型面经】

前言 在2026年AI大模型的面试中,常问的问题以及答案可能会涵盖多个方面,包括AI大模型的基础知识、训练过程、应用、挑战和前沿趋势等。由于我无法直接附上174题的完整面试题库及其答案,我将基于提供的信息和当前AI大模型领域的热点,给出一些常见的问题和答案示例。 1. 基础知识 问题:请简要介绍目前主流的大模型体系有哪些? 答案: 目前主流的大模型体系主要包括: * GPT系列:由OpenAI发布,基于Transformer架构的语言模型,包括GPT-1、GPT-2、GPT-3、ChatGPT等。这些模型具有强大的生成能力和语言理解能力。 * BERT:由Google发布,一种基于Transformer架构的双向预训练语言模型。BERT在多个自然语言处理任务上取得了显著效果。 * XLNet:由CMU和Google Brain发布,一种基于Transformer架构的自回归预训练语言模型。XLNet通过自回归方式预训练,能够建模全局依赖关系。 * RoBERTa:由Meta(原Facebook)发布,基于BERT进行改进,通过更大规模的数据和更长的训练时间,取得了更好

在家也能做 AI 导演!本地部署 Wan2.1 视频生成模型全攻略

在家也能做 AI 导演!本地部署 Wan2.1 视频生成模型全攻略

文章目录 * 前言 * 1.软件准备 * 1.1 ComfyUI * 1.2 文本编码器 * 1.3 VAE * 1.4 视频生成模型 * 2.整合配置 * 3. 本地运行测试 * 4. 公网使用Wan2.1模型生成视频 * 4.1 创建远程连接公网地址 * 5. 固定远程访问公网地址 * 总结 前言 Wan2.1 模型搭配 ComfyUI 框架,能实现文本转视频、图片转动画等功能,生成的视频质量可媲美专业工具,普通 PC 就能运行,特别适合自媒体创作者、短视频团队和 AI 爱好者快速制作动态内容,无需复杂技术背景也能上手,且完全开源免费,性价比很高。 使用时发现,选择模型版本要结合显卡配置:

AutoGPT+Python:让AI智能体自动完成复杂任务的终极指南

AutoGPT+Python:让AI智能体自动完成复杂任务的终极指南

AutoGPT+Python:让AI智能体自动完成复杂任务的终极指南 引言:在人工智能迈向自主化的新阶段,AutoGPT作为基于大语言模型(LLM)的自主智能体代表,正掀起一场让AI自己思考、自主执行的技术革命。当它遇上Python的全栈生态与极致灵活性,开发者不再只是调用AI接口,而是能深度定制专属智能体——让AI听懂自然语言、拆解复杂目标、调用外部工具、联网检索信息、迭代优化结果,独立完成从市场调研、内容创作、代码开发到自动化运维的全流程任务。 本文从核心原理、本地部署、Python实战、插件扩展、生产优化五大维度,手把手带你从0到1搭建可落地、可监控、可进化的AI智能体系统,不管是AI爱好者、全栈开发者还是创业者,都能靠这份指南,掌握下一代人机协作的核心生产力。 一、先搞懂:AutoGPT到底是什么? 传统ChatGPT类模型是被动应答,你问一句它答一句,需要人工一步步引导;而AutoGPT是自主智能体,你只给它一个最终目标,它就能自己完成: * 任务拆解:把复杂目标拆成可执行子步骤 * 自主决策:判断下一步该做什么、调用什么工具 * 记忆管理:短期记忆存上下文

OpenClaw 为什么突然爆火?从上门安装到排队体验,我看到的 AI Agent 破圈真相

OpenClaw 为什么突然爆火?从上门安装到排队体验,我看到的 AI Agent 破圈真相

🔥 个人主页:杨利杰YJlio❄️ 个人专栏:《Sysinternals实战教程》《Windows PowerShell 实战》《WINDOWS教程》《IOS教程》《微信助手》《锤子助手》《Python》《Kali Linux》《那些年未解决的Windows疑难杂症》🌟 让复杂的事情更简单,让重复的工作自动化 OpenClaw 为什么突然爆火?从上门安装到排队体验,我看到的 AI Agent 破圈真相 * 1、OpenClaw 这次为什么让我有点震撼? * 2、OpenClaw 到底是什么?它和普通聊天 AI 有什么不同? * 2.1 普通大模型解决的是“回答问题” * 2.2 OpenClaw 这类 Agent 试图解决的是“帮我完成任务” * 3、从控制台截图看,它已经不是“纯概念”了 * 4、