基于 Solidity 0.8.25 和 ChainLink Automation 的智能合约自动化演示项目。当银行合约的存款超过设定阈值时,自动转移一半存款到合约所有者地址。
本项目实现了一个支持 ChainLink Automation 的银行合约,具有以下核心功能:
- ✅ 用户存款和提取功能
- ✅ 基于阈值的自动化触发机制
- ✅ ChainLink Automation 集成
- ✅ 安全的资金管理
- ✅ 现代化的 Web 前端界面
chainLink/
├── Bank.sol # 主合约文件
├── deploy.js # 部署脚本
├── package.json # 项目依赖
├── .env.example # 环境变量示例
├── index.html # 前端界面
├── app.js # 前端逻辑
└── README.md # 项目文档
-
存款功能 (
deposit())- 用户可以向合约存入 ETH
- 记录每个用户的存款余额
- 触发存款事件
-
提取功能 (
withdraw())- 用户可以提取自己的存款
- 安全检查确保余额充足
-
自动化检查 (
checkUpkeep())- 检查总存款是否超过阈值
- 验证时间间隔是否满足(最小1小时)
- 确认合约余额充足
-
自动化执行 (
performUpkeep())- 当条件满足时自动执行
- 转移一半存款到合约所有者
- 更新相关状态变量
-
管理功能
- 更新触发阈值(仅所有者)
- 紧急提取功能(仅所有者)
- 状态查询功能
本合约完全兼容 ChainLink Automation 标准:
- 实现了
checkUpkeep()接口用于条件检查 - 实现了
performUpkeep()接口用于自动执行 - 支持链下计算和链上执行的分离
- Node.js >= 16.0.0
- MetaMask 钱包
- Sepolia 测试网 ETH
- 合约地址 : 0xcE3BE1592Ec695FF5c311839f3b1399158f6AbaB
- 前端框架: 原生 HTML/CSS/JavaScript
- Web3 库: Ethers.js v6.x
- 智能合约: Solidity 0.8.25
- 自动化服务: ChainLink Automation
- 测试网络: Sepolia
npm install复制 .env.example 为 .env 并填入配置:
cp .env.example .env编辑 .env 文件:
RPC_URL=https://sepolia.infura.io/v3/YOUR_INFURA_KEY
PRIVATE_KEY=your_private_key_here
DEFAULT_THRESHOLD=1000000000000000000 # 1 ETH- 打开 Remix IDE
- 创建新文件并复制
Bank.sol内容 - 编译合约(Solidity 0.8.25)
- 连接 MetaMask 到 Sepolia 测试网
- 部署合约,设置初始阈值(如 1 ETH = 1000000000000000000 wei)
### 4. 启动前端界面
直接在浏览器中打开 `index.html` 文件,或使用本地服务器:
```bash
# 使用 Python 启动本地服务器
python -m http.server 8000
# 或使用 Node.js
npx http-server
注意: 前端已升级到 Ethers.js v6,具有以下改进:
- 更现代的 API 设计
- 更好的类型安全性
- 优化的性能表现
- 使用 CDN 加载,无需本地安装
-
连接钱包
- 点击"连接钱包"按钮
- 确保连接到 Sepolia 测试网
-
设置合约地址
- 在"合约地址"输入框中输入已部署的合约地址
- 系统会自动验证地址有效性
-
存款操作
- 输入存款金额(ETH)
- 点击"存款"按钮
- 确认 MetaMask 交易
-
监控自动化状态
- 查看"ChainLink Automation 状态"面板
- 点击"检查 Upkeep 状态"更新状态
- 当所有条件满足时,可手动执行或等待自动执行
# 验证合约状态
npm run verify <合约地址>
# 测试存款
npm run test-deposit <合约地址> <金额>
# 检查 Upkeep 状态
npm run check-upkeep <合约地址>-
重入攻击防护
- 使用 checks-effects-interactions 模式
- 状态更新在外部调用之前
-
权限控制
- 只有合约所有者可以更新阈值
- 只有合约所有者可以紧急提取
-
条件验证
performUpkeep()中重新验证所有条件- 防止恶意调用
-
时间锁定
- 最小1小时的转账间隔
- 防止频繁自动转账
运行需要20个link代币,可以通过节水来获取,或者通过uniswapv3 来用ETH 测试代币兑换
- 访问 ChainLink Automation
- 连接钱包并选择 Sepolia 网络
- 点击"Register New Upkeep"
- 填写以下信息:
- Target contract address: 您的合约地址
- Admin address: 管理员地址
- Gas limit: 500,000
- Starting balance: 5 LINK(用于支付 gas 费用)
- Check data: 0x(空字节)
在 Sepolia 测试网上,您可以从以下水龙头获取 LINK 代币:
- 部署合约,设置阈值为 1 ETH
- 多个用户存款,总额超过 1 ETH
- 等待1小时后,ChainLink Automation 自动执行转账
- 验证一半存款已转移到所有者地址
- 存款超过阈值且时间间隔满足
- 在前端点击"手动执行 Upkeep"
- 验证转账执行成功
- 存款未达到阈值
- 验证
checkUpkeep()返回 false - 确认不会执行自动转账
合约发出以下事件,可用于监控和分析:
event Deposit(address indexed user, uint256 amount, uint256 newTotal);
event AutoTransfer(uint256 amount, uint256 remainingBalance, uint256 timestamp);
event ThresholdUpdated(uint256 oldThreshold, uint256 newThreshold);
event Withdrawal(address indexed user, uint256 amount);-
交易失败
- 检查 gas 费用是否充足
- 确认网络连接正常
- 验证合约地址正确
-
Upkeep 不执行
- 确认条件是否全部满足
- 检查 LINK 余额是否充足
- 验证时间间隔是否达到
-
前端连接问题
- 确认 MetaMask 已安装并解锁
- 检查网络是否为 Sepolia
- 刷新页面重新连接
// 在浏览器控制台中检查合约状态(Ethers.js v6 语法)
const provider = new ethers.BrowserProvider(window.ethereum);
const contract = new ethers.Contract(address, abi, provider);
await contract.getUpkeepStatus();
// 检查钱包连接状态
const signer = await provider.getSigner();
console.log('当前账户:', await signer.getAddress());
// 格式化金额显示
const balance = await contract.balances(userAddress);
console.log('用户余额:', ethers.formatEther(balance), 'ETH');欢迎提交 Issue 和 Pull Request!
- Fork 本仓库
- 创建功能分支
- 提交更改
- 发起 Pull Request
MIT License - 详见 LICENSE 文件
本项目仅用于学习和演示目的。请勿在主网使用真实资金进行测试。使用前请充分了解智能合约的风险。

