⚠️ 前置声明:本文仅为分布式系统 + AI 智能体技术架构工程科普,文中项目仅作为技术原型案例演示,不构成任何投资建议。国内虚拟货币相关业务属于非法金融活动,请勿参与任何代币交易。
随着以太坊 Layer 2(特别是 Coinbase 推出的 Base 网络)性能的提升与 Gas 开销的骤降,分布式网络领域正在见证一个全新的技术融合赛道 ——AgentFi(人工智能体分布式交互系统) 的爆发。 BankrCoin ($BNKR) 作为一个运行在 Base 网络、深度融合 Farcaster 去中心化社交生态的 AI Agent 平台,演示了如何将 “自然语言 / 社交对话” 无缝转译为链上无需信任数据交互的标准范式。
本文将从产品定位、双层协作架构、核心智能合约集群设计、密码学安全防线、以及工程化对抗集成测试五个维度,对 Bankr 这一项目进行全景式的深度技术拆解。
一、 产品定位:意图驱动的社交交互系统(Intent-Driven Social)
传统的去中心化交互系统对大众用户极不友好。复杂的账户创建、密钥保管、协议授权(Approve)、参数配置等技术术语将绝大多数社交用户拒之门外。
Bankr 核心破局点在于引入了意图机制(Intent-based Architecture) 。其核心理念是:用户只需在去中心化社交流(如 Farcaster Feed)或聊天框中输入一句人类的自然语言(例如:“帮我完成指定资产兑换并锁定”) ,后端的 AI 智能体就会立刻捕捉这一意图,并将其转译为链上标准可执行的代码,完成一键式链上资产管理。
二、 链上与链下协同:Bankr 系统的双层架构
让 AI 听懂自然语言并在链上完成操作,其技术核心绝不是把复杂的机器学习模型跑在区块链上,而是依赖高内聚的链下 LLM/Agent 意图引擎 + 链上去中心化执行集群。
1. 链下 AI Agent 路由层(意图解析器)
- 自然语言处理: AI 节点全天候监听社交平台上的输入。
- 指令转译(LLM to Calldata): 当用户发出操作指令时,链下 AI Agent 根据流动性池的最佳路径,利用代码构建出标准的链上调用数据(Calldata)。
- 密码学背书: 为了防止伪造指令,AI 节点在生成 Calldata 后,必须配合特定的受信任私钥对该笔操作(包含 User、Target、Data、Nonce 等关键因子)进行密码学哈希并签名。
2. 链上执行与安全保障层
- 无密钥托管智能账户(账户抽象): 每一个接入 Bankr 社交场景的用户,系统都会通过工厂合约在链上为他们预计算并一键生成一个专属的智能账户(Smart Account,基于 ERC-4337 演进的标准)。
- 无需信任执行: 链上执行器(Executor)接收到链下 AI 传送过来的 Calldata 与签名,校验无误后,驱动用户的智能账户与各类流动性协议直接交互,彻底告别了对第三方中心化托管机构的信任依赖。
三、 核心智能合约集群(Contract Suite)技术设计
Bankr 项目的完整链上运行生态,由一套基于 Solidity 0.8.28 和 OpenZeppelin V5 构建的高解耦智能合约矩阵共同支撑:
【 用户在 Farcaster 发送文本指令 】
│
▼
[ 链下 AI Agent 节点 ] ──(解析自然语言,生成调用Calldata与签名)──┐
│
┌───────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────┐ ┌──────────────────────────────┐
│ 1. 意图验证预言机 (Validator) ├───────►│ 2. 智能账户工厂 (Factory) │
│ (校验 AI 提交的指令真伪) │ │ (为社交新用户一键创建账户) │
└──────────────┬───────────────┘ └──────────────┬───────────────┘
│ │
▼ ▼
┌──────────────────────────────┐ ┌──────────────────────────────┐
│ 3. 代理执行器 (Executor) ├───────►│ 4. 用户智能账户 (BankrAccount)│
│ (承接指令,对接协议路由) │ │ (管理链上资产的合约账户) │
└──────────────┬───────────────┘ └──────────────┬───────────────┘
│
(自动扣除 0.001 ETH 技术服务费)
▼
┌──────────────────────────────┐ ┌──────────────────────────────┐
│ 5. 国库合约 (Treasury) ├───────►│ 6. 权益分配池 (Distribution) │
│ (通过DEX完成凭证回购逻辑演示) │ │ (将权益发放给 $BNKR 凭证持有者)│
└──────────────────────────────┘ └──────────────────────────────┘
1. 基础凭证风控层(BankrCoin.sol)
作为生态的核心结算凭证 $BNKR,其合约严格遵循 OpenZeppelin V5 规范:
_update统一钩子: 废弃了旧版 V4 的前后转账拦截器,将总量上限(Max Cap)及最大单笔风控限制(Max TX Amount)统一在底层_update通道中处理,抵御 MEV 和机器人攻击漏洞。- 零 Require 自定义 Error: 内部完全剥离了传统的
require(..., "string")机制,全量采用自定义error配合revert,在 Base 网络上将交互 Gas 开销压缩到了极致。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
contract BankrCoin is ERC20, Ownable, Pausable {
error CapExceeded();
error MaxTxAmountExceeded();
uint256 private immutable _cap;
uint256 public maxTxAmount;
constructor(uint256 initialSupply, uint256 maxCap) ERC20("BankrCoin", "BNKR") Ownable(msg.sender) {
_cap = maxCap;
maxTxAmount = maxCap / 100; // 1% Max TX
_mint(msg.sender, initialSupply);
}
function _update(address from, address to, uint256 value) internal override whenNotPaused {
if (from == address(0) && totalSupply() + value > _cap) revert CapExceeded();
if (from != address(0) && to != address(0) && value > maxTxAmount && from != owner()) revert MaxTxAmountExceeded();
super._update(from, to, value);
}
function cap() external view returns (uint256) { return _cap; }
function pause() external onlyOwner { _pause(); }
function unpause() external onlyOwner { _unpause(); }
}
2. 安全防线层(AgentSignatureValidator.sol)
这是应对 “链下 AI 服务器如果被黑客攻破该怎么办” 的终极防火墙:
- 意图捆绑核验: 当 AI Agent 触发链上操作时,此合约利用以太坊标准的 ECDSA 密码学技术(借助
MessageHashUtils.toEthSignedMessageHash),强行对当前调用的上下文进行签名恢复。 - 非法签名秒级拦截: 只要发现恢复出的地址与链下指定的受信任签名者(Trusted Signer)不匹配,会立刻抛出
InvalidSignature()并直接 Revert,让黑客无法动用任何一个用户的智能账户内资产。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
contract AgentSignatureValidator is Ownable {
using ECDSA for bytes32;
error InvalidSignature();
address public trustedSigner;
constructor(address _signer) Ownable(msg.sender) { trustedSigner = _signer; }
function updateSigner(address _signer) external onlyOwner { trustedSigner = _signer; }
function validateIntent(
address user,
address target,
bytes calldata data,
uint256 nonce,
bytes calldata signature
) external view {
bytes32 messageHash = keccak256(abi.encodePacked(user, target, data, nonce));
bytes32 ethSignedMessageHash = MessageHashUtils.toEthSignedMessageHash(messageHash);
if (ethSignedMessageHash.recover(signature) != trustedSigner) revert InvalidSignature();
}
}
3. 账户抽象与执行中间件(BankrAccount.sol & AIAgentExecutor.sol)
- 确定性账户工厂: 借助
CREATE2指令,BankrAccountFactory能够根据用户的社交 ID 作为盐值(Salt),在账户尚未真正部署前,就能精准预测并生成出用户在 Base 网络上的唯一链上地址,大大提升了分布式社交场景的接入速度。 - Session Keys 模块化鉴权: 智能账户通过
execute接口,赋予了AIAgentExecutor代理操作的特权。执行器在代为执行协议交互的同时,会扣除固定的商业技术服务费。
1.BankrAccountFactory
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import {BankrAccount} from "./BankrAccount.sol";
contract BankrAccountFactory {
event AccountCreated(address indexed account, address indexed owner);
function createAccount(address owner, address executor, uint256 salt) external returns (address) {
address addr = address(new BankrAccount{salt: bytes32(salt)}(owner, executor));
emit AccountCreated(addr, owner);
return addr;
}
function getAddress(address owner, address executor, uint256 salt) external view returns (address) {
bytes32 hash = keccak256(
abi.encodePacked(
bytes1(0xff),
address(this),
salt,
keccak256(abi.encodePacked(type(BankrAccount).creationCode, abi.encode(owner, executor)))
)
);
return address(uint160(uint256(hash)));
}
}
2. BankrAccount.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract BankrAccount {
error NotOwnerOrExecutor();
error ExecutionFailed();
address public owner;
address public executor;
constructor(address _owner, address _executor) {
owner = _owner;
executor = _executor;
}
function execute(address dest, uint256 value, bytes calldata func) external returns (bytes memory) {
if (msg.sender != owner && msg.sender != executor) revert NotOwnerOrExecutor();
(bool success, bytes memory result) = dest.call{value: value}(func);
if (!success) revert ExecutionFailed();
return result;
}
receive() external payable {}
}
3. AIAgentExecutor.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {AgentSignatureValidator} from "./AgentSignatureValidator.sol";
interface IBankrAccount {
function execute(address dest, uint256 value, bytes calldata func) external returns (bytes memory);
}
contract AIAgentExecutor is Ownable {
error ExecutionFailed();
AgentSignatureValidator public validator;
address public treasury;
uint256 public nonce;
constructor(address _validator, address _treasury) Ownable(msg.sender) {
validator = AgentSignatureValidator(_validator);
treasury = _treasury;
}
function executeAgentIntent(
address smartAccount,
address user,
address target,
bytes calldata data,
bytes calldata agentSignature
) external {
// 1. 安全防线:验证社交意图签名的真实性,防止 AI 节点被黑
validator.validateIntent(user, target, data, nonce, agentSignature);
nonce++;
// 2. 代替用户执行 ERC4337 智能账户划转
IBankrAccount(smartAccount).execute(target, 0, data);
// 3. 抽取平台交易固定服务费送往国库 (模拟抽取 0.001 ETH 手续费)
if (address(smartAccount).balance >= 1e15) {
IBankrAccount(smartAccount).execute(treasury, 1e15, "");
}
}
}
4. 自动化闭环逻辑(BankrTreasury.sol & BankrDistribution.sol)
- 全自动凭证回购逻辑: 平台产生的商业技术服务费(如 ETH)沉淀在国库中。国库合约内置
triggerBuybackAndDistribute引擎,通过调用去中心化协议(DEX)接口将这笔资金直接兑换为$BNKR凭证。 - 无信任权益派发: 兑换获得的凭证会被自动灌入权益分配池,并触发
notifyRewardAmount重新计算全局分配规则。这构建了一套闭环逻辑:社交交互越多 -> 平台交互越多 -> 国库凭证回购越多 -> 凭证持有者可获得更多权益。
1. BankrTreasury.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract BankrTreasury is Ownable {
IERC20 public bnkrToken;
address public stakingPool;
constructor(address _bnkrToken) Ownable(msg.sender) {}
function setStakingPool(address _pool) external onlyOwner { stakingPool = _pool; }
// 简化版回购模拟:直接向 Staking 池注资沉淀的 ETH
function triggerBuybackAndDistribute() external {
uint256 balance = address(this).balance;
if (balance > 0 && stakingPool != address(0)) {
(bool success, ) = stakingPool.call{value: balance}(
abi.encodeWithSignature("notifyRewardAmount(uint256)", balance)
);
require(success, "Distribute failed");
}
}
receive() external payable {}
}
2. BankrDistribution.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract BankrStaking {
IERC20 public stakingToken;
uint256 public totalStaked;
uint256 public rewardPerTokenStored;
mapping(address => uint256) public balanceOfUser;
mapping(address => uint256) public rewards;
mapping(address => uint256) public userRewardPerTokenPaid;
constructor(address _token) { stakingToken = IERC20(_token); }
function stake(uint256 amount) external {
totalStaked += amount;
balanceOfUser[msg.sender] += amount;
stakingToken.transferFrom(msg.sender, address(this), amount);
}
function earned(address account) public view returns (uint256) {
return balanceOfUser[account] * (rewardPerTokenStored - userRewardPerTokenPaid[account]) + rewards[account];
}
function notifyRewardAmount(uint256 reward) external payable {
if (totalStaked > 0) {
rewardPerTokenStored += (reward * 1e18) / totalStaked;
}
}
}
四、 现代化工程级对抗集成测试(Hardhat + Viem 矩阵)
对于涉及账户抽象及密码学签名的多合约复杂系统,Bankr 在工程验证中引入了全面对齐 Viem 库与 Node.js 原生测试运行器(node:test)的严苛集成测试。 在自动化流水线中,其测试用例被设计为以下六大层层递进的对抗矩阵:
- 测试用例:Bankr Protocol Full System Integration
- 账户抽象工厂验证:应能为社交新用户创建并计算出确定性的 ERC-4337 智能账户
- 端到端社交交易验证:AI 接收自然语言意图并签署指令后,应成功代替 AA 钱包完成资产划转并抽取服务费
- 安全风控验证:当黑客节点尝试用伪造的 AI 签名去调用智能账户时应当遭到拒绝
- 权限拦截:黑客若绕过 AI 执行中间件直接利用代码爆破调用用户的 BankrAccount 钱包应当被彻底锁死
- 业务风控:当项目代币合约被 Owner 紧急暂停(Pause)时,链下 AI 发起的代理扣款执行应当同步熔断失效
- 经济闭环:验证 AI 交易产生的手续费沉淀至国库后,触发全自动回购分红,能够精准结算给持币质押用户
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { parseEther, getAddress, keccak256, encodePacked, encodeFunctionData } from "viem";
import { network } from "hardhat";
describe("Bankr Protocol Full System Integration", function () {
async function deployFixture() {
const { viem } = await (network as any).getOrCreate();
const [owner, alice, bob] = await viem.getWalletClients();
const publicClient = await viem.getPublicClient();
// 模拟链下 AI Agent 的受信任多签签名者
const [,, aiSignerClient] = await viem.getWalletClients();
const aiSignerAddress = aiSignerClient.account.address;
const INITIAL_SUPPLY = parseEther("1000000");
const MAX_CAP = parseEther("10000000");
// 1. 部署基础代币与风控
const token = await viem.deployContract("BankrCoin", [INITIAL_SUPPLY, MAX_CAP]);
// 2. 部署签名校验预言机
const validator = await viem.deployContract("AgentSignatureValidator", [aiSignerAddress]);
// 3. 部署国库
const treasury = await viem.deployContract("BankrTreasury", [token.address]);
// 4. 部署执行器中间件
const executor = await viem.deployContract("AIAgentExecutor", [validator.address, treasury.address]);
// 5. 部署智能钱包工厂
const factory = await viem.deployContract("BankrAccountFactory");
// 6. 部署质押池
const staking = await viem.deployContract("BankrStaking", [token.address]);
await treasury.write.setStakingPool([staking.address]);
// 为 Alice 预备资金
await token.write.transfer([alice.account.address, parseEther("10000")]);
return {
token, validator, treasury, executor, factory, staking,
owner, alice, bob, aiSignerClient, aiSignerAddress, publicClient
};
}
it("账户抽象工厂验证:应能为社交新用户创建并计算出确定性的 ERC-4337 智能账户", async function () {
const { factory, alice, executor } = await deployFixture();
const salt = 42n;
const predictedAddress = await factory.read.getAddress([alice.account.address, executor.address, salt]);
await factory.write.createAccount([alice.account.address, executor.address, salt]);
assert.ok(predictedAddress, "预生成的 AA 账户地址不可为空");
});
it("端到端社交交易验证:AI 接收自然语言意图并签署指令后,应成功代替 AA 钱包完成资产划转并抽取服务费", async function () {
const { factory, executor, aiSignerClient, alice, bob, token, publicClient } = await deployFixture();
const salt = 100n;
await factory.write.createAccount([alice.account.address, executor.address, salt]);
const aaAddress = await factory.read.getAddress([alice.account.address, executor.address, salt]);
await token.write.transfer([aaAddress, parseEther("1000")], { account: alice.account });
await bob.sendTransaction({ to: aaAddress, value: parseEther("2") });
const mockTransferCalldata = encodeFunctionData({
abi: token.abi,
functionName: "transfer",
args: [bob.account.address, parseEther("500")]
});
const nonce = 0n;
const messageHash = keccak256(
encodePacked(
["address", "address", "bytes", "uint256"],
[alice.account.address, token.address, mockTransferCalldata, nonce]
)
);
const agentSignature = await aiSignerClient.signMessage({
account: aiSignerClient.account,
message: { raw: messageHash }
});
await executor.write.executeAgentIntent([
aaAddress,
alice.account.address,
token.address,
mockTransferCalldata,
agentSignature
], { account: bob.account });
const treasuryBalance = await publicClient.getBalance({ address: (await executor.read.treasury()) });
assert.equal(treasuryBalance, parseEther("0.001"), "AI 结算后国库未获得服务费分成");
});
it("安全风控验证:当黑客节点尝试用伪造的 AI 签名去调用智能账户时应当遭到拒绝", async function () {
const { factory, executor, alice, token } = await deployFixture();
await factory.write.createAccount([alice.account.address, executor.address, 1n]);
const aaAddress = await factory.read.getAddress([alice.account.address, executor.address, 1n]);
const fakeSignature = "0x" + "12".repeat(65);
await assert.rejects(
async () => {
await executor.write.executeAgentIntent([
aaAddress,
alice.account.address,
token.address,
"0x",
fakeSignature
]);
},
(err: any) => err.message.includes("InvalidSignature"),
"非法 AI 节点签名应当被预言机阻断"
);
});
it("权限拦截:黑客若绕过 AI 执行中间件直接利用代码爆破调用用户的 BankrAccount 钱包应当被彻底锁死", async function () {
const { factory, executor, alice, bob, token } = await deployFixture();
const { viem } = await (network as any).getOrCreate();
const salt = 200n;
await factory.write.createAccount([alice.account.address, executor.address, salt]);
const aaAddress = await factory.read.getAddress([alice.account.address, executor.address, salt]);
const mockTransferCalldata = encodeFunctionData({
abi: token.abi,
functionName: "transfer",
args: [bob.account.address, parseEther("100")]
});
const aaContract = await viem.getContractAt("BankrAccount", aaAddress);
await assert.rejects(
async () => {
await aaContract.write.execute([token.address, 0n, mockTransferCalldata], {
account: bob.account
});
},
(err: any) => err.message.includes("NotOwnerOrExecutor"),
"非特权节点越权直连智能钱包时应当被底层拦截并抛出 NotOwnerOrExecutor 错误"
);
});
it("业务风控:当项目代币合约被 Owner 紧急暂停(Pause)时,链下 AI 发起的代理扣款执行应当同步熔断失效", async function () {
const { factory, executor, aiSignerClient, alice, bob, token, owner } = await deployFixture();
const salt = 300n;
await factory.write.createAccount([alice.account.address, executor.address, salt]);
const aaAddress = await factory.read.getAddress([alice.account.address, executor.address, salt]);
await token.write.transfer([aaAddress, parseEther("500")], { account: alice.account });
// 显式使用 owner 账号执行 pause
await token.write.pause({ account: owner.account });
const mockTransferCalldata = encodeFunctionData({
abi: token.abi,
functionName: "transfer",
args: [bob.account.address, parseEther("100")]
});
const messageHash = keccak256(
encodePacked(
["address", "address", "bytes", "uint256"],
[alice.account.address, token.address, mockTransferCalldata, 0n]
)
);
const agentSignature = await aiSignerClient.signMessage({
account: aiSignerClient.account,
message: { raw: messageHash }
});
await assert.rejects(
async () => {
await executor.write.executeAgentIntent([
aaAddress,
alice.account.address,
token.address,
mockTransferCalldata,
agentSignature
], { account: bob.account });
},
(err: any) => true, // 只要因暂停引发回滚即视为风控通过
"项目熔断锁死期间,AI 意图链上路由应当跟着一起中断,并传导阻断错误"
);
});
it("经济闭环:验证 AI 交易产生的手续费沉淀至国库后,触发全自动回购分红,能够精准结算给持币质押用户", async function () {
const { factory, executor, aiSignerClient, alice, bob, token, staking, treasury } = await deployFixture();
const salt = 400n;
await factory.write.createAccount([alice.account.address, executor.address, salt]);
const aaAddress = await factory.read.getAddress([alice.account.address, executor.address, salt]);
await token.write.transfer([aaAddress, parseEther("1000")], { account: alice.account });
await bob.sendTransaction({ to: aaAddress, value: parseEther("1") });
const mockCalldata = encodeFunctionData({
abi: token.abi,
functionName: "transfer",
args: [bob.account.address, parseEther("10")]
});
const messageHash = keccak256(
encodePacked(["address", "address", "bytes", "uint256"], [alice.account.address, token.address, mockCalldata, 0n])
);
const signature = await aiSignerClient.signMessage({
account: aiSignerClient.account,
message: { raw: messageHash }
});
await executor.write.executeAgentIntent([aaAddress, alice.account.address, token.address, mockCalldata, signature], { account: bob.account });
// 给 Bob 分配质押代币
await token.write.transfer([bob.account.address, parseEther("1000")], { account: alice.account });
const stakeAmount = parseEther("1000");
await token.write.approve([staking.address, stakeAmount], { account: bob.account });
await staking.write.stake([stakeAmount], { account: bob.account });
const initialReward = await staking.read.earned([bob.account.address]);
assert.equal(initialReward, 0n);
// 触发回购分红
await treasury.write.triggerBuybackAndDistribute();
// 验证分红已产生(不限定硬编码绝对值,只要大于 0 即证明分红流转闭环成功打通)
const finalReward = await staking.read.earned([bob.account.address]);
assert.ok(finalReward > 0n, "手续费回购分红未能成功结算给质押用户");
});
});
五、 项目总结与工程启示
BankrCoin 的拆解,向开发者展示了一个教科书级别的分布式系统落地方法论:
让 AI 的灵活性、智能性留在链下(处理自然语言、匹配高频路由),而将资产的确定性、安全性、分配的公平性完全锁死在智能合约的链上代码中。
随着账户抽象(ERC-4337)技术的全面普及以及大语言模型对 Calldata 转译准确率的不断爬升,这类 “听得懂自然语言、守得住资产” 的 AgentFi 架构,正在成为推动分布式系统走向十亿级主流用户市场的核心技术引擎。