引言
随着大语言模型(LLM)的全面普及与自主 AI 智能体(AI Agents)在软件工程(如 Claude Code, Cursor)、自动化流水线中的爆发式增长,AI 推理开销(Inference Cost)已成为现代技术型企业与独立开发者最核心的运营成本。
在这个背景下,全球算力调度市场呈现出一个巨大的悖论:需求端正苦于高昂的原生 API 账单,而供给端却存在大量的闲置产能。许多通过企业级批发协议提前购买了海量推理额度或算力套餐的大型机构,由于业务波动,其额度往往用不完,只能白白过期作废。
本文设计了一套创新分布式 AI 基础设施原型,用于解决闲置 API 推理额度的调度分配问题。我们可以把这套架构理解为一套 AI 推理算力订单簿与额度撮合系统。其核心愿景:就像大宗商品拥有标准化交易撮合系统,AI 推理闲置额度也可以搭建一套高效的调度撮合网络。
本文将解析这套系统的商业调度逻辑、网络运作机制,并从底层技术出发,深入解析如何基于最新的 Solidity 0.8.28 与 OpenZeppelin V5 规范,构建其高性能、低延迟的分布式账本结算与状态通道架构。
一、 Surplus 运作机制:颠覆性的“API额度再分配”
传统招募 GPU 资源聚合物理算力的分布式网络不同,这套原型另辟蹊径,主打的是 API 接口额度的流动性聚合与再分配。
1. 双向调度市场
- 供给端(Sellers) :持有 OpenAI、Anthropic、Google 等兼容接口或闲置 API 额度的机构与个人,可将闲置额度接入系统,设置可接受的最低报价。
- 需求端(Buyers) :开发者不需要修改任何业务代码,只需在已有的 AI SDK 中将请求的
base_url切换为本系统统一路由接口,即可在单一 API 下一键集成涵盖文本、图像、多模态的 300 多种主流大模型(如 GPT, Claude, Llama, Gemini, DeepSeek)。
2. 毫秒级链下订单簿路由
当买家的 AI 智能体发起调用请求时,系统会像交易所订单簿一样,自动、毫秒级地将请求路由至链下当前报价最低、服务状态健康的供给通道执行。引入闲置产能竞价机制后,使用者能够获得可观的成本缩减,部分模型推理成本可大幅下降。
二、 核心技术痛点:高频推理与链上清算的冲突
AI 推理请求通常是毫秒级、高频次的,单次网络请求的费用极低(常常不足 $0.001)。如果每次 API 调用都由智能合约在链上进行实时撮合与扣款,高昂的 Gas 费和不可控的区块链延迟将使系统彻底瘫痪。
为了实现去中心化与高性能的兼得,Surplus 必须采用 “链下匹配高频交易,链上托管分批结算” 的状态通道(State Channel) 合约架构:
- 资金托管与质押:买家预先将稳定币(如 USDC)存入合约建立消费资金池;卖家(算力提供商)必须质押最低额度的保证金(SLA Deposit),防止其提供虚假、不可用的 API 响1. 应。
- 链下增量签名(State Channel Voucher) :当买家调用 AI API 时,每消费一笔,便在链下利用私钥生成一个加密状态通道签名发送给卖家。该签名记录的是历史累计消费总额。
- 链上异步清算(Asynchronous Settlement) :卖家无需高频上链,只需定期将买家最新的累计签名快照提交至智能合约。合约通过密码学还原出买家身份后,一次性执行扣款并转账,实现“万次请求,一次清算”。
三、 基于 Solidity 0.8.28 与 OpenZeppelin V5 的核心合约实现
1. 多模型结算池工厂合约:SurplusPoolFactory.sol
为了支持不同的支付结算代币(如 USDC、原生代币 $SURPLUS)或隔离不同性能的算力池,通过工厂模式动态管理多个独立的结算池。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./SurplusMarketplace.sol";
/**
* @title SurplusPoolFactory
* @notice 用于动态部署和管理不同结算代币或不同规则的 Surplus 推理市场的工厂合约
*/
contract SurplusPoolFactory is Ownable {
// 记录所有部署的结算池地址
address[] public allPools;
// 映射:代币地址 => 部署的结算池
mapping(address => address[]) public tokenToPools;
event PoolCreated(address indexed poolAddress, address indexed token, uint256 minStake);
constructor() Ownable(msg.sender) {}
/**
* @notice 部署一个新的推理结算池
* @param _token 结算使用的 ERC20 代币地址
* @param _minSupplierStake 卖家入驻所需的最低质押额度
*/
function createPool(address _token, uint256 _minSupplierStake) external onlyOwner returns (address) {
// 实例化基于 OZ V5 标准的结算合约
// 将当前工厂合约的 Owner 传递为新合约的 Owner,或者直接传 msg.sender
SurplusMarketplace newPool = new SurplusMarketplace(_token, _minSupplierStake, msg.sender);
address poolAddr = address(newPool);
allPools.push(poolAddr);
tokenToPools[_token].push(poolAddr);
emit PoolCreated(poolAddr, _token, _minSupplierStake);
return poolAddr;
}
function getPoolsCount() external view returns (uint256) {
return allPools.length;
}
}
2. 状态通道结算合约:SurplusMarketplace.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
/**
* @title SurplusMarketplace
* @notice 基于 OpenZeppelin V5 和 Solidity 0.8.28 实现的去中心化 AI 推理算力托管结算合约(增强版)
*/
contract SurplusMarketplace is Ownable, ReentrancyGuard, Pausable {
using ECDSA for bytes32;
// --- 状态变量 ---
IERC20 public immutable usdcToken;
uint256 public minSupplierStake;
mapping(address => uint256) public balances;
mapping(address => uint256) public supplierStakes;
// 核心账本:记录【买家 => 卖家 => 链下累计历史总消费额】
mapping(address => mapping(address => uint256)) public settledAmounts;
// --- OpenZeppelin V5 自定义错误 (极大地优化 Gas 消耗) ---
error ZeroAmount();
error TransferFailed();
error InsufficientBalance(uint256 available, uint256 required);
error StakeTooLow(uint256 provided, uint256 required);
error SupplierNotActive();
error InvoiceOverageInvalid(uint256 current, uint256 previous);
error InvalidSignature();
// --- 事件 ---
event Deposit(address indexed user, uint256 amount);
event Withdraw(address indexed user, uint256 amount);
event SupplierRegistered(address indexed supplier, uint256 stake);
event SupplierWithdrawn(address indexed supplier, uint256 amount);
event SettlementExecuted(address indexed consumer, address indexed supplier, uint256 totalAmount, uint256 paymentPaid);
constructor(
address _usdcToken,
uint256 _minSupplierStake,
address _initialOwner
) Ownable(_initialOwner) {
if (_usdcToken == address(0)) revert TransferFailed();
usdcToken = IERC20(_usdcToken);
minSupplierStake = _minSupplierStake;
}
/**
* @notice 买家存入 资金额度,支持链下高频 AI 推理消费
*/
function depositFunds(uint256 _amount) external whenNotPaused nonReentrant {
if (_amount == 0) revert ZeroAmount();
if (!usdcToken.transferFrom(msg.sender, address(this), _amount)) revert TransferFailed();
balances[msg.sender] += _amount;
emit Deposit(msg.sender, _amount);
}
/**
* @notice 买家提取未消费的预存额度
*/
function withdrawFunds(uint256 _amount) external nonReentrant {
if (_amount == 0) revert ZeroAmount();
if (balances[msg.sender] < _amount) revert InsufficientBalance(balances[msg.sender], _amount);
balances[msg.sender] -= _amount;
if (!usdcToken.transfer(msg.sender, _amount)) revert TransferFailed();
emit Withdraw(msg.sender, _amount);
}
/**
* @notice 卖家(算力/API 额度提供方)注册并质押保证金,激活接单资格
*/
function registerSupplier(uint256 _stakeAmount) external whenNotPaused nonReentrant {
if (_stakeAmount < minSupplierStake) revert StakeTooLow(_stakeAmount, minSupplierStake);
if (!usdcToken.transferFrom(msg.sender, address(this), _stakeAmount)) revert TransferFailed();
supplierStakes[msg.sender] += _stakeAmount;
emit SupplierRegistered(msg.sender, supplierStakes[msg.sender]);
}
/**
* @notice 卖家退出或减少保证金
*/
function withdrawSupplierStake(uint256 _amount) external nonReentrant {
if (_amount == 0) revert ZeroAmount();
if (supplierStakes[msg.sender] < _amount) revert InsufficientBalance(supplierStakes[msg.sender], _amount);
supplierStakes[msg.sender] -= _amount;
if (!usdcToken.transfer(msg.sender, _amount)) revert TransferFailed();
emit SupplierWithdrawn(msg.sender, _amount);
}
/**
* @notice 核心业务:卖家凭买家链下签名的状态通道凭证来链上批量清算提款
* @param _consumer 买家(消费者)地址
* @param _totalCumulativeAmount 链下累计消耗的总金额(必须为历史总和快照)
* @param _signature 买家对该累计快照的 EIP-191 密码学签名
*/
function settleInvoice(
address _consumer,
uint256 _totalCumulativeAmount,
bytes calldata _signature
) external whenNotPaused nonReentrant {
address supplier = msg.sender;
// 1. 校验卖家当前质押状态是否合规
if (supplierStakes[supplier] < minSupplierStake) revert SupplierNotActive();
// 2. 校验金额有效性(提交的快照必须大于该买家对该卖家的历史已结算总和)
uint256 previouslySettled = settledAmounts[_consumer][supplier];
if (_totalCumulativeAmount <= previouslySettled) {
revert InvoiceOverageInvalid(_totalCumulativeAmount, previouslySettled);
}
// 3. 密码学签名验证:还原买家在链下使用钱包或智能体私钥生成的签名
bytes32 messageHash = keccak256(abi.encodePacked(_consumer, supplier, _totalCumulativeAmount, address(this)));
bytes32 ethSignedMessageHash = MessageHashUtils.toEthSignedMessageHash(messageHash);
address signer = ethSignedMessageHash.recover(_signature);
if (signer != _consumer) revert InvalidSignature();
// 4. 计算本次应付差额并校验买家资金池
uint256 paymentDue = _totalCumulativeAmount - previouslySettled;
if (balances[_consumer] < paymentDue) revert InsufficientBalance(balances[_consumer], paymentDue);
// 5. 更新状态(遵循检查-生效-交互原则,防止重入)
balances[_consumer] -= paymentDue;
settledAmounts[_consumer][supplier] = _totalCumulativeAmount;
// 6. 转账给算力提供商
if (!usdcToken.transfer(supplier, paymentDue)) revert TransferFailed();
emit SettlementExecuted(_consumer, supplier, _totalCumulativeAmount, paymentDue);
}
// --- 治理与安全风控函数 (仅限治理代币持有人/Owner 操作) ---
function setMinSupplierStake(uint256 _newStake) external onlyOwner {
minSupplierStake = _newStake;
}
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
}
四、 完备性集成测试:viem 与 node:test 实战
- 完备测试用例:Surplus Intelligence Protocol Full Integration
- 初始化验证:工厂合约应正确部署结算池并绑定正确的代币和最低质押
- 资金与托管:买家充值和提现应正确变更账本余额
- 卖家生命周期:卖家应能注册质押并可撤回保证金
- 核心业务(状态通道清算):卖家应能凭借买家的合规密码学签名进行链上按需批量扣款
- 安全风控(防重放与篡改):篡改清算金额或重放旧签名应当被拒绝
- 安全风控(紧急暂停):管理员暂停合约后,应立刻拦截交易并在恢复后正常运行
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { parseUnits, keccak256, encodePacked, getAddress } from "viem";
import { network } from "hardhat";
describe("Surplus Intelligence Protocol Full Integration", function () {
// 统一的配置参数
const MIN_STAKE = parseUnits("50", 6); // 50 USDC (6位小数)
const INITIAL_BALANCE = parseUnits("500", 6); // 预存 500 USDC
async function deployFixture() {
// 修复警告:使用新版推荐的 (network as any).create() 代替 connect()
const { viem } = await (network as any).create();
// 获取钱包客户端,其中包含账户和私钥能力
const [owner, consumer, supplier, attacker] = await viem.getWalletClients();
const publicClient = await viem.getPublicClient();
// 1. 部署 6 位的 MockUSDC 代币
const mockUSDC = await viem.deployContract("MockERC20", ["MockUSDC", "USDC", 6]);
// 2. 部署工厂合约 (基于 OZ V5 标准)
const factory = await viem.deployContract("SurplusPoolFactory");
// 3. 通过工厂合约创建一个支持 MockUSDC 的结算池
await factory.write.createPool([mockUSDC.address, MIN_STAKE], {
account: owner.account,
});
// 4. 获取动态部署出来的 Marketplace 结算池地址
const poolAddress = await factory.read.allPools([0n]);
const marketplace = await viem.getContractAt("SurplusMarketplace", poolAddress);
// 5. 准备测试资金与授权
// 给买家(Consumer)发钱并注入额度
await mockUSDC.write.mint([consumer.account.address, INITIAL_BALANCE]);
await mockUSDC.write.approve([marketplace.address, INITIAL_BALANCE], { account: consumer.account });
// 给卖家(Supplier)发钱并注入质押金
await mockUSDC.write.mint([supplier.account.address, MIN_STAKE]);
await mockUSDC.write.approve([marketplace.address, MIN_STAKE], { account: supplier.account });
return {
mockUSDC,
factory,
marketplace,
owner,
consumer,
supplier,
attacker,
publicClient,
};
}
it("初始化验证:工厂合约应正确部署结算池并绑定正确的代币和最低质押", async function () {
const { factory, marketplace, mockUSDC } = await deployFixture();
assert.equal(await factory.read.getPoolsCount(), 1n, "结算池数量应为 1");
assert.equal(
getAddress(await marketplace.read.usdcToken()),
getAddress(mockUSDC.address),
"结算代币不匹配"
);
assert.equal(await marketplace.read.minSupplierStake(), MIN_STAKE, "最低质押额不匹配");
});
it("资金与托管:买家充值和提现应正确变更账本余额", async function () {
const { marketplace, consumer } = await deployFixture();
const depositAmount = parseUnits("100", 6);
// 买家存入 100 额度
await marketplace.write.depositFunds([depositAmount], { account: consumer.account });
assert.equal(await marketplace.read.balances([consumer.account.address]), depositAmount);
// 买家提取 40 额度
const withdrawAmount = parseUnits("40", 6);
await marketplace.write.withdrawFunds([withdrawAmount], { account: consumer.account });
assert.equal(
await marketplace.read.balances([consumer.account.address]),
depositAmount - withdrawAmount
);
});
it("卖家生命周期:卖家应能注册质押并可撤回保证金", async function () {
const { marketplace, supplier } = await deployFixture();
// 卖家入驻质押
await marketplace.write.registerSupplier([MIN_STAKE], { account: supplier.account });
assert.equal(await marketplace.read.supplierStakes([supplier.account.address]), MIN_STAKE);
// 卖家撤回部分保证金
const withdrawStake = parseUnits("10", 6);
await marketplace.write.withdrawSupplierStake([withdrawStake], { account: supplier.account });
assert.equal(
await marketplace.read.supplierStakes([supplier.account.address]),
MIN_STAKE - withdrawStake
);
});
it("核心业务(状态通道清算):卖家应能凭借买家的合规密码学签名进行链上按需批量扣款", async function () {
const { marketplace, consumer, supplier } = await deployFixture();
// 1. 卖家和买家完成质押与充值
await marketplace.write.depositFunds([INITIAL_BALANCE], { account: consumer.account });
await marketplace.write.registerSupplier([MIN_STAKE], { account: supplier.account });
// 2. 模拟链下高频 AI 推理消费:买家产生价值 30 USDC 的消费总额
const totalCumulativeAmount = parseUnits("30", 6);
// 3. 构建与合约中相同的 keccak256(abi.encodePacked(...)) 消息哈希
const messageHash = keccak256(
encodePacked(
["address", "address", "uint256", "address"],
[consumer.account.address, supplier.account.address, totalCumulativeAmount, marketplace.address]
)
);
// 4. 买家使用私钥对消息哈希进行 EIP-191 标准签名
const signature = await consumer.signMessage({ message: { raw: messageHash } });
// 5. 卖家拿着买家的累计清算快照及签名,上链提款清算
await marketplace.write.settleInvoice(
[consumer.account.address, totalCumulativeAmount, signature],
{ account: supplier.account }
);
// 6. 断言检查:买家扣除 30 刀,卖家获得 30 刀
assert.equal(
await marketplace.read.balances([consumer.account.address]),
INITIAL_BALANCE - totalCumulativeAmount
);
// 【💡 修复处】:多参数映射传参时,必须放在同一个外层数组内
assert.equal(
await marketplace.read.settledAmounts([consumer.account.address, supplier.account.address]),
totalCumulativeAmount
);
});
it("安全风控(防重放与篡改):篡改清算金额或重放旧签名应当被拒绝", async function () {
const { marketplace, consumer, supplier, attacker } = await deployFixture();
await marketplace.write.depositFunds([INITIAL_BALANCE], { account: consumer.account });
await marketplace.write.registerSupplier([MIN_STAKE], { account: supplier.account });
const realAmount = parseUnits("50", 6);
const messageHash = keccak256(
encodePacked(
["address", "address", "uint256", "address"],
[consumer.account.address, supplier.account.address, realAmount, marketplace.address]
)
);
const signature = await consumer.signMessage({ message: { raw: messageHash } });
// 恶意情况 A:卖家贪心,链下收到 50 刀的凭证,试图上链改成提款 500 刀
const fakeAmount = parseUnits("500", 6);
await assert.rejects(
async () => {
await marketplace.write.settleInvoice(
[consumer.account.address, fakeAmount, signature],
{ account: supplier.account }
);
},
/InvalidSignature/, // 触发 OpenZeppelin V5 的自定义 Error 拦截
"金额被篡改后签名应失效"
);
// 恶意情况 B:第三方黑客(或未激活的卖家)拿着偷来的合法签名试图去执行清算
await assert.rejects(
async () => {
await marketplace.write.settleInvoice(
[consumer.account.address, realAmount, signature],
{ account: attacker.account }
);
},
/SupplierNotActive/,
"未足额质押的黑客无法执行清算"
);
});
it("安全风控(紧急暂停):管理员暂停合约后,应立刻拦截交易并在恢复后正常运行", async function () {
const { marketplace, owner, consumer } = await deployFixture();
const amount = parseUnits("10", 6);
// 1. Owner 触发暂停 (OZ Pausable 标准)
await marketplace.write.pause({ account: owner.account });
// 2. 充值动作应当被熔断拦截
await assert.rejects(
async () => {
await marketplace.write.depositFunds([amount], { account: consumer.account });
},
/EnforcedPause/ // OpenZeppelin V5 的默认暂停 Error 错误匹配
);
// 3. 解除暂停后应能够重新操作
await marketplace.write.unpause({ account: owner.account });
await marketplace.write.depositFunds([amount], { account: consumer.account });
assert.equal(await marketplace.read.balances([consumer.account.address]), amount);
});
});
五、 总结与生产级扩展思考
Surplus Intelligence 并不自己生产算力,它通过将僵硬的企业级大模型批发额度转化成具备高流动性的链上商品,实现了算力的高效流动与再分配。通过基于 Solidity 0.8.28 与 OpenZeppelin V5 的技术改造,其底层核心合约在大幅优化 Gas 开销的同时,利用状态通道和增量清算机制完美抹平了 Web3 高昂手续费与高频 AI 推理之间的天然鸿沟。
在向真实的工业级生产环境推进时,该系统还需要补齐去中心化纠纷与挑战机制(Challenge Period) 。因为状态通道依赖于链下交互的诚信度。若卖家提供虚假响应却强行上链结算,买家应当可以通过智能体多签预言机发起欺诈挑战,从而扣除卖家的保证金。这种密码学技术与次级自由市场的交融,正加速推动着下一代智能体经济(Agent Economy)的破茧成蝶。