Agent链上操作的技术挑战:从“能跑“到“安全运行“
Agent链上操作的技术挑战:从"能跑"到"安全运行"
AI Agent与区块链结合的核心命题不是"能否让Agent发送交易"——这是LangChain + ethers.js组合在技术层面已经解决的问题。真正的挑战在于:如何定义Agent在链上操作的权限边界,如何在Agent被攻击或做出错误决策时限制损失,以及如何协调多个Agent的链上协作而不引入新的安全漏洞。
7月在AI Agent的安全研究方向上有几个重要进展:OpenAI发布了对Agent系统安全评估的Preparedness Framework更新、a16z crypto发表了Agent自治许可(Agent Authorization Framework)的讨论稿、以及Safe Wallet团队开源了支持AI Agent多签操作的安全模块原型。
本文将这些分散的信息整合为一套Agent链上操作的技术框架,涵盖权限模型、安全边界和协作框架三个维度。
二、Agent链上操作的权限模型架构
权限控制层是Agent安全的核心防线。它不是简单地"允许/禁止Agent操作",而是一个多层次的过滤系统:
- 操作白名单规定了Agent可以调用的合约地址和函数选择器(例如只允许调用特定DeFi协议的swap函数,不允许调用任意合约的任意函数)
- 金额上限限制单次操作的最大资金量(例如单次swap限额10 ETH)
- 时间窗口限制高频操作(例如每小时最多3笔交易)
- 多签策略要求高影响操作需要至少m-of-n个Agent或人类签名
三、Agent安全框架的代码实现
Safe Wallet + AI Agent多签模块
// contracts/AgentSafeModule.sol
// Safe Wallet的AI Agent安全模块 —— 继承Safe的模块体系
//
// 设计决策:
// 1. 模块化设计 —— 作为Safe的Module安装在多签钱包上,
// 而非修改Safe核心合约。Agent的权限可以通过
// enableModule / disableModule 随时开启和关闭
// 2. 双重限制: 函数白名单 + 金额上限 ——
// 操作白名单防御未知函数调用(approve恶意代币),
// 金额上限防御Agent决策错误导致的资金损失,
// 两者叠加形成"纵深防御"
// 3. 冷却期机制 —— 大额交易不是拒绝而是延迟,
// 给人类操作者一个时间窗口审查和取消交易
// 采用ERC-4337风格的UserOperation队列实现
// 4. 执行窗口 —— Agent只能在指定时间段内操作,
// 非窗口期所有交易拒绝,防止非工作时间无人监控
import {Safe} from "@safe-global/safe-contracts/contracts/Safe.sol";
import {Enum} from "@safe-global/safe-contracts/contracts/common/Enum.sol";
contract AgentSafeModule {
// ===== 权限定义 =====
struct AgentPermissions {
bool active; // 该Agent是否被授权
uint256 maxSingleTxValue; // 单笔交易最大ETH金额
uint256 maxDailyVolume; // 每日累计最大ETH金额
uint256 dailyVolumeUsed; // 当日已使用金额
uint256 lastDayReset; // 上次日重置的时间戳
uint256 cooldownThreshold; // 触发冷却期的金额阈值
uint256 cooldownDuration; // 冷却期时长(秒)
mapping(bytes4 => bool) allowedFunctions; // 函数选择器白名单
mapping(address => bool) allowedContracts; // 合约地址白名单
}
// Agent地址 → 权限配置
mapping(address => AgentPermissions) public agentPermissions;
// 执行窗口: startHour ~ endHour (UTC小时)
uint256 public executionWindowStart = 0; // 默认全天
uint256 public executionWindowEnd = 24;
// 待执行的冷却期交易
struct QueuedTransaction {
address to;
uint256 value;
bytes data;
uint256 queuedAt;
uint256 expiresAt;
}
mapping(bytes32 => QueuedTransaction) public cooldownQueue;
// 事件 —— 链上审计追踪
event AgentTxProposed(
address indexed agent,
address indexed to,
uint256 value,
bytes4 selector,
bytes32 queueId
);
event AgentTxExecuted(
address indexed agent,
bytes32 queueId,
bool success
);
event AgentTxCancelled(bytes32 queueId, address canceller);
event AgentSuspended(address indexed agent, string reason);
/**
* @notice Agent提交交易 —— 经权限检查、冷却期检查、窗口期检查
*/
function executeFromAgent(
address to,
uint256 value,
bytes calldata data,
Enum.Operation operation
) external returns (bool) {
address agent = msg.sender;
AgentPermissions storage perm = agentPermissions[agent];
// 检查1: Agent是否激活
require(perm.active, "Agent not authorized");
// 检查2: 执行窗口时间
uint256 hour = (block.timestamp % 86400) / 3600;
require(
hour >= executionWindowStart && hour < executionWindowEnd,
"Outside execution window"
);
// 检查3: 合约白名单
require(perm.allowedContracts[to], "Contract not in whitelist");
// 检查4: 函数选择器白名单
bytes4 selector = bytes4(data[:4]);
require(perm.allowedFunctions[selector], "Function not in whitelist");
// 检查5: 金额上限
_resetDailyVolumeIfNeeded(perm);
require(
perm.dailyVolumeUsed + value <= perm.maxDailyVolume,
"Daily volume exceeded"
);
// 检查6: 大额交易冷却期
if (value >= perm.cooldownThreshold) {
bytes32 queueId = keccak256(
abi.encodePacked(agent, to, value, data, block.timestamp)
);
cooldownQueue[queueId] = QueuedTransaction({
to: to,
value: value,
data: data,
queuedAt: block.timestamp,
expiresAt: block.timestamp + perm.cooldownDuration
});
emit AgentTxProposed(agent, to, value, selector, queueId);
return false; // 需要人工确认
}
// 通过所有检查: 执行交易并更新日统计
perm.dailyVolumeUsed += value;
bool success = Safe(msg.sender).execTransactionFromModule(
to, value, data, operation
);
emit AgentTxExecuted(agent, bytes32(0), success);
return success;
}
/**
* @notice 人类操作者确认冷却期交易
*/
function confirmCooldownTx(bytes32 queueId) external {
QueuedTransaction storage tx_ = cooldownQueue[queueId];
require(tx_.queuedAt > 0, "Transaction not found");
require(block.timestamp < tx_.expiresAt, "Transaction expired");
// 执行交易
Safe(msg.sender).execTransactionFromModule(
tx_.to, tx_.value, tx_.data, Enum.Operation.Call
);
emit AgentTxExecuted(msg.sender, queueId, true);
delete cooldownQueue[queueId];
}
/**
* @notice 任何人可以在冷却期内取消交易
*/
function cancelCooldownTx(bytes32 queueId) external {
require(cooldownQueue[queueId].queuedAt > 0, "Transaction not found");
emit AgentTxCancelled(queueId, msg.sender);
delete cooldownQueue[queueId];
}
function _resetDailyVolumeIfNeeded(AgentPermissions storage perm) internal {
if (block.timestamp - perm.lastDayReset >= 86400) {
perm.dailyVolumeUsed = 0;
perm.lastDayReset = block.timestamp;
}
}
}
Agent端的权限调用封装
// agent/safe_client.ts
// AI Agent → Safe Wallet 交互客户端
//
// 设计决策:
// 1. 使用 viem 的 WalletClient 发送交易 ——
// viem 的 Account 抽象支持 private key / mnemonic / HSM
// Agent使用独立的EOA作为签名者,而非共享人类操作者的账户
// 2. 交易模拟优先于实际执行 ——
// 通过 Tenderly Simulation API 在 fork 环境中预执行交易,
// 检查: 是否会revert、状态变化是否符合预期、Gas消耗是否异常
// 模拟失败的交易不会发送到mempool
// 3. 决策记录上链 —— Agent的每次推理决策写入合约事件,
// 作为不可篡改的审计日志
import { createWalletClient, http, encodeFunctionData, parseAbi } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { mainnet } from 'viem/chains';
const SAFE_ADDRESS = '0x...';
const AGENT_MODULE_ADDRESS = '0x...';
const agentModuleAbi = parseAbi([
'function executeFromAgent(address to, uint256 value, bytes data, uint8 operation) returns (bool)',
]);
export class AgentSafeClient {
private walletClient;
private agentAccount;
constructor(agentPrivateKey: `0x${string}`, rpcUrl: string) {
this.agentAccount = privateKeyToAccount(agentPrivateKey);
this.walletClient = createWalletClient({
account: this.agentAccount,
chain: mainnet,
transport: http(rpcUrl),
});
}
/**
* Agent调用Safe模块执行交易
*
* @param to - 目标合约地址 (必须在白名单中)
* @param value - ETH金额 (必须≤单笔上限)
* @param calldata - 编码后的函数调用
* @returns 交易哈希或null(冷却期排队)
*/
async executeTransaction(
to: `0x${string}`,
value: bigint,
calldata: `0x${string}`
): Promise<`0x${string}` | null> {
// Step 1: Tenderly模拟交易
const simulationOk = await this.simulateTransaction(to, value, calldata);
if (!simulationOk) {
throw new Error('Transaction simulation failed');
}
// Step 2: 调用Safe模块的executeFromAgent
const txHash = await this.walletClient.writeContract({
address: AGENT_MODULE_ADDRESS,
abi: agentModuleAbi,
functionName: 'executeFromAgent',
args: [to, value, calldata, 0], // operation=0 (Call)
});
return txHash;
}
private async simulateTransaction(
to: `0x${string}`,
value: bigint,
calldata: `0x${string}`
): Promise<boolean> {
// 调用Tenderly Simulation API
const response = await fetch(
`https://api.tenderly.co/api/v1/account/me/project/project/simulate`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': process.env.TENDERLY_ACCESS_KEY!,
},
body: JSON.stringify({
network_id: '1',
from: SAFE_ADDRESS,
to,
input: calldata,
value: value.toString(),
save: false, // 不保存模拟结果
save_if_fails: true, // 仅保存失败结果用于调试
}),
}
);
const result = await response.json();
return result.simulation?.status === true;
}
}
四、安全边界:Agent链上操作的反面模式
反模式1——Agent拥有私钥的全部控制权:架构上将Agent的私钥直接存储在运行环境的环境变量中,Agent可以发送任意交易。这是最危险的模式——一旦Agent的推理被操纵(例如prompt注入让Agent"把所有ETH转给攻击者"),没有任何人工防线可以阻止。正确的做法是Agent永远无法直接签名交易——它只能向Safe模块提交"交易提案",由模块验证权限后再决定执行或排队等待人工确认。
反模式2——多Agent共享同一Safe且无操作隔离:如果有多个Agent(例如一个Agent负责价格监控、一个负责自动调仓、一个负责收益收割)共享同一个Safe钱包,需要确保每个Agent的权限配置是独立的。一个Agent的每日限额被另一Agent的误操作消耗完毕,会导致三个Agent同时停摆。为每个Agent分配独立的权限配置条目(通过Agent地址区分)是基础要求。
反模式3——完全自动化的"自动驾驶"模式:Agent全自动执行所有交易,没有人工干预窗口。这在技术上可行(让模块永不过期地缓存冷却期交易),但在安全上危险。任何bug、攻击或异常市场条件都可能在几分钟内耗尽Safe中的全部资金。最小的人工干预窗口是必要的——至少对于超过一定金额的交易,应该有12-24小时的冷却期。
五、总结
AI Agent在区块链上的操作安全性,本质上是一个"权限最小化"问题——不是让Agent"能做什么",而是将Agent的权限精确限制在"它确实需要做的那些事情"上。7月的实践表明,Solidity层面的Safe模块 + 函数白名单 + 金额上限 + 冷却期机制是一套足够健壮的防御体系,它平衡了"Agent自动化操作的效率"和"资金安全的底线要求"。
8月需要重点关注的方向:跨链Agent的操作同步(Agent在L1上做出的决策如何安全地在L2上执行)、Agent决策的ZK证明(让Agent的LLM推理过程附带一个ZK证明,链上合约验证证明了推理的"逻辑正确性")、以及多Agent博弈场景下的协作协议(多个Agent如何在DeFi中合作而不会被任何一个Agent的恶意行为拖垮整个系统)。
资料说明
本文中的协议、版本、性能、成本和行业趋势应以可核验的一手资料为准。未标注统计口径的比例、时间表和预测仅作工程讨论,不应视为行业事实。可参考 0731 资料来源索引,并在发布前将具体来源贴到对应断言之后。
更多推荐


所有评论(0)