Web3

2025年07月12日更新 6 人订阅
原价: ¥ 10 限时优惠
专栏简介 Web3 学习之私钥保护 ——将私钥导入加密密钥库 Web3实战:使用web3modal SDK实现钱包连接并部署在Vercel React 学习之 createElement Web3 学习之钱包与链上交易速度问题以及与传统交易系统的对比 Web3 学习之GAS 机制与手续费详解 Web3学习之去中心化交易所(DEX) Web3学习之Uniswap Web3学习之Uniswap V2 的手续费计算 Web3学习之 ERC20 Web3学习之使用Foundry开发部署和开源ERC20合约 Foundry 高级实战:实现一个可升级的工厂合约 UpgradeableTokenFactory 升级合约源码分析 OpenZeppelin Foundry Upgrades upgradeProxy 深入解析 Uniswap V2 的手续费计算:公式推导与代码详解 全面指南:构建与部署以太坊多签钱包(MultiSigWallet)智能合约的最佳实践 利用 Chainlink Automation 自动化 Bank 合约:使用 Solidity 实现动态存款管理和自动转账 利用 Chainlink VRF 实现100 Token抽奖:从名单中随机选出幸运得主的完整指南 Op-Stack架构全景图:Layer 2 架构详解 钱包地址生成和作用 浏览器扩展、网页工具 require,revert,和assert的使用场景分别是什么样的? library 在使用上有什么限制 fallback 如何防范 ApproveScam 漏洞 透明代理 vs UUPS:智能合约升级模式全景解析与实用指南 MPC钱包和多签钱包的区别:一文看懂 BIP39和BIP44:你的加密货币钱包安全基石 Qtum 量子链:UTXO 交易的深度解析与实操指南 探索数据库系统:从概念到应用的全景概览 Solidity on Polkadot: Web3 实战开发指南 Web3 实践:在 Polkadot 上用 Solidity 玩转 Delegatecall Web3 新星:Monad 打造 NFT 全解 Ethers.js 实战:带你掌握 Web3 区块链开发 Web3 开发入门:用 Ethers.js 玩转以太坊交易与合约 玩转 Web3:用 Viem 库实现以太坊合约部署与交互 Web3新速度:Monad与BuyEarth DApp重塑虚拟世界 Web3开发必知:Solidity内存布局(Storage、Memory、Stack)解析 以太坊大变革:Vitalik 提议用RISC-V重塑未来! Web3实战:打造属于你的NFT数字资产 Web3 数据索引新利器:用 The Graph 打造 NFT 市场子图全攻略 用 Python 解锁 Web3:以太坊日志解析实战 Web3 数据神器:用 Go 解锁以太坊事件解析 用 Rust 解锁 Web3:以太坊事件解析实战 Web3 实战:解锁 Monad MCP,轻松查询 MON 余额 Web3 开发神器:Arbitrum Stylus 智能合约全攻略 解锁Web3未来:Rust与Solidity智能合约实战 Web3 新体验:Blink 一键解锁 Monad 未来 Alloy 赋能 Web3:Rust 区块链实战 Web3 开发实战:用 Foundry 高效探索以太坊区块链 Web3 金融:Uniswap V2 资金效率深度剖析 Uniswap V3 流动性机制与限价订单解析:资金效率提升之道 用 Rust 打造 Web3 区块链浏览器:从零开始的实战指南 探索Web3新速度:Sonic高性能Layer-1上的BlindAuction智能合约实践 Uniswap V2 合约部署全攻略:Web3 实践指南 重磅!国家级智库为人民币稳定币“出招”,上海香港或将联动!

利用 Chainlink Automation 自动化 Bank 合约:使用 Solidity 实现动态存款管理和自动转账

利用ChainlinkAutomation自动化Bank合约:使用Solidity实现动态存款管理和自动转账概述在这篇文章中,我们将实现一个Bank合约,用户可以通过deposit()方法存款。我们将使用ChainlinkAutomation来自动化合约任务,实现当存

利用 Chainlink Automation 自动化 Bank 合约:使用 Solidity 实现动态存款管理和自动转账

概述

在这篇文章中,我们将实现一个 Bank 合约,用户可以通过 deposit() 方法存款。我们将使用 Chainlink Automation 来自动化合约任务,实现当存款超过指定阈值时,自动将一半的存款转移到指定的地址(如合约拥有者)。

Bank 合约代码

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {AutomationCompatibleInterface} from "@chainlink/contracts/src/v0.8/automation/AutomationCompatible.sol";

contract Bank is AutomationCompatibleInterface {
    address public owner;
    uint256 public threshold;
    mapping(address => uint256) public balances;

    event Deposited(address indexed user, uint256 amount);
    event Withdrawn(address indexed user, uint256 amount);

    constructor(uint256 _threshold) {
        owner = msg.sender;
        threshold = _threshold;
    }

    function deposit() public payable {
        require(msg.value > 0, "Deposit must be greater than 0");
        balances[msg.sender] += msg.value;
        emit Deposited(msg.sender, msg.value);
    }

    function getBalance() external view returns (uint256) {
        return address(this).balance;
    }

    function setThreshold(uint256 _newThreshold) external {
        require(msg.sender == owner, "Only owner can set the threshold");
        threshold = _newThreshold;
    }

    // checkUpKeep():在链下间隔执行调用该函数, 该方法返回一个布尔值,告诉网络是否需要自动化执行。
    function checkUpkeep(
        bytes calldata /* checkData */
    )
        external
        view
        override
        returns (bool shouldTransferFunds, bytes memory /* performData */)
    {
        shouldTransferFunds = (address(this).balance > threshold);
    }

    // performUpKeep():这个方法接受从checkUpKeep()方法返回的信息作为参数。Chainlink Automation 会触发对它的调用。函数应该先进行一些检查,再执行链上其他计算。
    function performUpkeep(bytes calldata /* performData */) external override {
        if (address(this).balance > threshold) {
            uint256 halfBalance = address(this).balance / 2;
            // payable(owner).transfer(halfBalance);
            (bool success, ) = payable(owner).call{value: halfBalance}("");
            require(success, "Transfer failed");
        }
    }

    function withdraw() external {
        require(msg.sender == owner, "Only owner can withdraw");
        payable(msg.sender).transfer(address(this).balance); // 转账给调用者
    }

    // Receive function to accept direct Ether transfers
    receive() external payable {
        deposit();
    }

    // Fallback function to handle any calls to non-existent functions
    fallback() external payable {
        deposit();
    }
}

使用 需要实现两个方法

  • checkUpKeep():在链下间隔执行调用该函数, 该方法返回一个布尔值,告诉网络是否需要自动化执行。

  • performUpKeep():这个方法接受从checkUpKeep()方法返回的信息作为参数。Chainlink Automation 会触发对它的调用。函数应该先进行一些检查,再执行链上其他计算。

更多请参考:https://docs.chain.link/chainlink-automation/guides/compatible-contracts

在上面代码中,

We don't use the checkData in this example. The checkData is defined when the Upkeep was registered.

We don't use the performData in this example. The performData is generated by the Automation Node's call to your checkUpkeep function

测试步骤

  1. 设置阈值:首先,确保合约部署时设置了适当的阈值(例如 0.008 ETH)。

  2. 执行存款

    • 第一步:调用 deposit() 方法,存入 0.008 ETH。
    • 第二步:再次调用 deposit() 方法,存入 0.002 ETH。
  3. 查询余额

    • 调用 getBalance() 方法,检查合约的余额是否超过设定的阈值。若余额超过阈值,performUpkeep() 方法将自动执行,余额应减少一半,转账到拥有者地址。
  4. 验证自动化

    • 使用 Chainlink Automation 的工具或界面确认自动化任务是否已执行,检查合约余额和拥有者地址的交易记录。

Chainlink Automation 实操

第一步:部署合约

部署脚本

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Script, console} from "forge-std/Script.sol";
import {Bank} from "../src/Bank.sol";

contract BankScript is Script {
    Bank public bank;
    uint256 threshold = 0.008 ether;

    function setUp() public {}

    function run() public {
        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
        vm.startBroadcast(deployerPrivateKey);

        bank = new Bank(threshold);
        console.log("Bank deployed to:", address(bank));

        vm.stopBroadcast();
    }
}

部署实操


hello-chainlink on  main [!?] via 🅒 base 
➜ source .env

hello-chainlink on  main [!?] via 🅒 base 
➜ forge script --chain sepolia BankScript --rpc-url $SEPOLIA_RPC_URL --broadcast --verify -vvvv  

[⠊] Compiling...
No files changed, compilation skipped
Traces:
  [381711] BankScript::run()
    ├─ [0] VM::envUint("PRIVATE_KEY") [staticcall]
    │   └─ ← [Return] <env var value>
    ├─ [0] VM::startBroadcast(<pk>)
    │   └─ ← [Return] 
    ├─ [334903] → new Bank@0x647f8FF9aa0AFC1d560a0C1366734B1f188Aa896
    │   └─ ← [Return] 1451 bytes of code
    ├─ [0] console::log("Bank deployed to:", Bank: [0x647f8FF9aa0AFC1d560a0C1366734B1f188Aa896]) [staticcall]
    │   └─ ← [Stop] 
    ├─ [0] VM::stopBroadcast()
    │   └─ ← [Return] 
    └─ ← [Stop] 

Script ran successfully.

== Logs ==
  Bank deployed to: 0x647f8FF9aa0AFC1d560a0C1366734B1f188Aa896

## Setting up 1 EVM.
==========================
Simulated On-chain Traces:

  [334903] → new Bank@0x647f8FF9aa0AFC1d560a0C1366734B1f188Aa896
    └─ ← [Return] 1451 bytes of code

==========================

Chain 11155111

Estimated gas price: 9.442339362 gwei

Estimated total gas used for script: 535661

Estimated amount required: 0.005057892944988282 ETH

==========================

##### sepolia
✅  [Success]Hash: 0x8e76814070931a6835a077724977a64537ddbae22dec2d916ec8f793b4a48340
Contract Address: 0x647f8FF9aa0AFC1d560a0C1366734B1f188Aa896
Block: 6473990
Paid: 0.002084410794718675 ETH (412147 gas * 5.057445025 gwei)

✅ S...

剩余50%的内容订阅专栏后可查看

点赞 1
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论