用 AWS CDK 构建以太坊智能合约持续集成与交付实战(下)

·

在上一篇 用 AWS CDK 构建以太坊智能合约持续集成与交付实战(上) 中,我们已经梳理了 dApp 团队协作的常见痛点、CI/CD 价值,以及所需 AWS 服务的“鸟瞰图”。本篇将全流程落在代码与配置上:手把手拆解 AWS CDK Stack 各构造器,让你 30 分钟内就能跑通一套可弹性伸缩、支持本地 Besu 私链 + Goerli 测试网的完整通道。为了让文章在中文技术圈更易于检索,核心关键词已自然嵌入:以太坊智能合约、CI/CD 管道、AWS CDK、Amazon ECS、Hyperledger Besu、Hardhat、Amazon Secrets Manager、Amazon EFS

解决方案总览

与上篇一致,我们依旧用一张简易架构图串起全局**:

  1. 开发者将 .sol 合约推送到 CodeCommit 仓库
  2. CodePipeline 触发 CodeBuild → 编译 & 部署
  3. 产物上传 Lambda + API Gateway,前端即刻感知变更
  4. Besu 私链及 Goerli 网络分别由 Amazon ECS on FargateManaged Blockchain 托管

仅凭一条 cdk deploy 命令即可全量拉起。

👉 10 分钟速通 AWS CDK 实战项目源代码与运行手册

AWS CDK 项目目录结构

bin/
├── cdk-stack.ts             // 所有构造器定义
lib/
├── DataSyncTaskExec/        // 将 S3 文件同步至 EFS 的自定义资源
├── ECSTaskExec/             // 启动 ECS Fargate Task 的自定义资源
├── EFSManagement/           // 初始化 EFS 目录/权限
resources/
├── BucketFiles/             // 需要上传到 S3 的中间文件
│   ├── BlockchainDevLayer.zip
│   ├── config.toml
│   ├── dev.json
│   ├── hardhat.config.js
│   └── deploy.js
├── StaticFiles/             // CodeBuild buildspec
│   ├── besubuildspec.yml
│   └── goerlibuildspec.yml
└── ShareToWinCode/          // dApp 源码压缩包

这样一来,新人打开仓库立刻知道「我改哪里」「配什么」,团队磨合成本骤降。

Ethereum 本地开发网络:Hyperledger Besu

任何 Solidity 工程师都明白:测试网水龙头有限、本地 Ganache 单点难共享。于是我们采用 Hyperledger Besu + AWS Fargate + Amazon EFS 的组合,让私链变成“团队共享即服务”。

ECS TaskDefinition 关键片段

const besuTaskDef = new ecs.FargateTaskDefinition(this, "BesuDevTaskDef", {
  cpu: 2048,
  memoryLimitMiB: 4096,
  executionRole: besuRole,
  taskRole: besuRole,
  volumes: [{
    name: "BesuEfsVolume",
    efsVolumeConfiguration: {
      fileSystemId: efs.fileSystemId,
      transitEncryption: "ENABLED",
      authorizationConfig: {
        accessPointId: efsAccessPoint.accessPointId,
        iam: "ENABLED"
      }
    }
  }]
});

钱包地址预置文件

⚠️ 请务必仅在开发网络使用,勿将其助记词泄露到生产

FAQ 1:为什么要放在 EFS?
A:EFS 支持多容器并发读写,Besu 节点停机重启时数据不会丢失,也方便挂载到其他侧链测试 Pod 做数据对比。

用 Amazon Secrets Manager 存储敏感参数

用途示例
BesuMnemonicString本地开发网络 10 个账户助记词
GeorliMnemonicString部署到 Goerli 使用
MainnetMnemonicString预留主网生产部署
AccessKey / SecretKeyCodeBuild 拉取 Managed Blockchain
BillingTokenUrlHTTP endpoint 同时签名避免过度授权

占位符在 CDK 中用 unsafePlainText("To be entered") 表示,部署完毕后务必手动更新。

S3 中转桶:一次上传、多处消费

👉 揭秘 Amazon S3 如何实现「一键发布」合约静态依赖

三大自定义资源(Custom Resource)深度解析

EFS 目录初始化 (EFSManagement)

Lambda 创建 /besu/config/besu/data,确保 Besu 启动即可写入权限账本。

S3→EFS 数据同步 (DataSyncTaskExec)

当 S3 里的 dev.json / config.toml 有更新,DataSync Task 自动同步到 EFS,省去人工 scp

ECS Task 按需启动 (ECSTaskExec)

CodeCommit & 触发策略

代码仓库结构保持一致:

ShareToWin-dApp/
├── SmartContractCode/contracts/AssetToken.sol
├── LambdaCode/index.mjs
├── package.json
└── test/

CodeBuild 双轨作业

Job Name网络buildspec 文件备注
BesuJob本地 Besubesubuildspec.yml秒级销毁,0 Gas 费压力测试
GoerliJobGoerligoerlibuildspec.yml验证与托管链交互逻辑

besubuildspec.yml 关键步骤

  1. 安装依赖
    npm ci --only=production
  2. 抓取配置
    aws s3 cp s3://bucket/hardhat.config.js .
  3. 编译 & 部署
    npx hardhat compile
    CONTRACT_ADDR=$(npx hardhat run --network besudev deploy.js)
  4. 触发测试
    npx hardhat test
  5. 若成功 → 更新 Lambda 代码与 CONTRACTADDRESS 环境变量

FAQ 2:失败回滚怎么样?
A:任一环节返回非 0,CodeBuild 立即标记 Pipeline 失败,不会产生 AWS 额外费用。可以配置 CloudWatch Alarm 用邮件或钉钉机器人提醒开发者。

FAQ 3:我想换成 Foundry 怎么办?
A:把 hardhat.config.js 换成 foundry.toml,然后再把编译命令改为 forge build && forge script 即可,不需要改动 IAM 与 S3 逻辑。

手动审批门槛

一键销毁实验环境

运行:

cdk destroy $STACK_NAME

将自动回收:

FAQ 4:如何只销毁 Besu 私链而保留数据?
A:把 EFS removalPolicy 设置成 RETAIN,再执行 destroy。次日重新部署,原有账本仍在 /data

结语 & 延伸

本篇通过 AWS CDK 代码级细节展示,将“以太坊智能合约 CI/CD 管道”落到可复用的工程模板:

下一步,你可以在同一个管道里:

  1. 引入 Amazon CodeGuru 做 Solidity 静态分析
  2. 部署 Grafana + Prometheus 监控节点性能并设置 RTE(Real Time Extract)
  3. 利用 Amazon EventBridge 把链上事件映射到 Slack 通知

👉 获取完整 CDK 工程模板,立即开跑?

FAQ 5:合约升级怎么办?
A:可将 deploy.js 替换为 OpenZeppelin Upgrades 插件,并把代理地址存回 Secrets Manager,下次 CI 流程自动识别是否首次部署还是升级。

FAQ 6:AWS 预算报警如何设置?
A:进入 Billing & Cost Management → Budget,把 Usage Type 限定为 ManagedBlockchain, CodeBuild, Fargate,超预算自动发送 SNS。


至此,一套 生产可用的以太坊智能合约 CI/CD 管道 已 100% Ready。祝各位开发者高效、安全且低成本地奔向 Web3!