18小时,AI帮我构建DeFi协议

这种规模的系统通常需要经验丰富的区块链工程师80到150小时才能搞定。使用Claude Code,配合完整的代码库上下文,我在大约18小时内就完成了端到端的构建。

18小时,AI帮我构建DeFi协议
一键发币: x402兼容 | Aptos | X Layer | SUI | SOL | BNB | ETH | BASE | ARB | OP | Polygon | Avalanche

我一直在听到一种无休止的论调,说AI正在催生新一代"10倍开发者"。说实话,我想看看这是真有其事,还是只是为了搭建React组件和构建简单UI包装器而制造的营销噱头。当你在受控环境中生成可预测的脚本时,很容易看起来像一位魔法师。但在去中心化金融领域,合约托管的是真实价值。执行跨越多个链,状态是碎片化且异步的,失败不仅仅是孤立的控制台错误。它们会恶意地跨系统边界级联传播。我需要知道AI是否真的能帮助构建在对抗性、跨链现实中存活的系统。

1、我构建了什么

为了测试这一点,我坐下来构建了一个跨链兑换协议。我设计了两条执行路径:通过Uniswap V3路由的同链兑换,以及利用LayerZero消息传递的跨链兑换。架构很重,依赖几个核心组件:

  • 路由合约: 决定执行路径的主要入口点。
  • 金库合约: 处理托管和协议记账。
  • 费用模块: 管理协议级别的计算和分配。
  • 桥接适配器: 直接与LayerZero端点交互。

我实现的一个简化的路由函数看起来像这样:

function executeSwap(
    address tokenIn,
    address tokenOut,
    uint256 amount,
    uint16 dstChainId,
    bytes calldata payload
) external payable {
    if (dstChainId == block.chainid) {
        _swapLocal(tokenIn, tokenOut, amount);
    } else {
        _swapCrossChain(tokenIn, tokenOut, amount, dstChainId, payload);
    }
}

这个抽象看起来很简洁。但很快我就会意识到,确保这两条路径的正确性完全是另一回事。

2、18小时的现实检验

一个这种规模的系统通常需要经验丰富的区块链工程师80到150小时才能搞定。这包括推理消息顺序、追踪边缘案例,以及处理分布式状态幽灵。使用Claude Code,配合完整的代码库上下文,我在大约18小时内就完成了端到端的构建。

让我描述一下在第14小时左右击中我的现实检验。是的,代码写完了,但我突然感受到一种沉重的认知负担——推理完全落在我的肩上。我感觉自己有一个高速打字员,可以以光速输出Solidity代码,但根本上不理解他们正在构建的世界的物理规律。

当我开始审计流程时,我发现了26个关键问题。我们谈论的是低效的状态更新、对非标准ERC20代币的灾难性假设、薄弱的访问控制,以及完全搞砸的跨链失败状态。每一个问题都需要手动检查、对跨链状态转换的显式推理,以及有针对性的修复。这是一个清醒的时刻。AI压缩了打字时间,但它并没有简化问题。

3、"高速打字员"表现出色的地方

公平地说,Claude在确定性任务的执行层表现出色。它快速完成了搭建继承结构和设置OpenZeppelin库的工作。如果我需要安全代币转账的标准实现或解码复杂载荷调用数据,它都能完美交付。

using SafeERC20 for IERC20;

function _safeTransfer(address token, address to, uint256 amount) internal {
    IERC20(token).safeTransfer(to, amount);
}
function _decodePayload(bytes calldata payload)
    internal
    pure
    returns (address token, uint256 amount)
{
    return abi.decode(payload, (address, uint256));
}

对于零歧义的明确定义问题,AI是一个强大的工具。它出色地处理这些局部的、有界约束的问题。

4、挣扎:我的提示词进化

我的整个工作流程依赖Claude Code,而我遇到的最大的摩擦点是我自己的提示词的进化。我一开始很随意,抛出一些以实现为驱动的指令,比如"写一个LayerZero接收合约",或"实现跨链兑换逻辑"。Claude照做了,快速吐出了功能代码。但它非常脆弱。它针对的是完成提示,而不是在主网上存活。

当我撞上一堵巨大的墙时,Claude完全遗漏了一个fee-on-transfer边缘案例,这个案例最终会让我们的金库失血。我意识到我的提示词必须进化成严格的系统级指令。我不再要求"一个路由",而是开始要求"在实现这个时假设跨链消息传递会被延迟、重新排序或完全失败。使用消息标识符确保幂等执行,并处理非标准rebase代币。"这种转变大大改善了输出,但它证明了一个根本性的限制。Claude对约束反应良好,但它不能独立推断它们。它缺乏对系统的全局理解,所以它的初始修复总是局部的而非架构性的。

5、逻辑崩溃的地方

当问题从编写孤立函数转向定义系统行为时,真正的局限性显露无遗。AI根本没有模拟跨链失败场景。它在应该使用内存时默认使用存储写入,生成不完整的访问边界,并完全忽略幂等性。

例如,Claude最初生成了一个非常天真的LayerZero接收器:

function lzReceive(...) external {
    _execute(payload);
}

我不得不强制它将执行包装在try/catch块中,以确保单个失败的消息不会永久阻塞通道:

mapping(bytes32 => bool) public processed;

function lzReceive(bytes32 messageId, bytes calldata payload) external {
    require(!processed[messageId], "Already processed");

    try this._execute(payload) {
        processed[messageId] = true;
    } catch {
        // 存储以供重试或手动干预
    }
}

同样,它完全忽略了fee-on-transfer机制,假设amountIn总是等于amountReceived。我必须手动强制执行正确的记账:

uint256 balanceBefore = IERC20(token).balanceOf(address(this));
IERC20(token).transferFrom(msg.sender, address(this), amount);
uint256 balanceAfter = IERC20(token).balanceOf(address(this));

uint256 actualReceived = balanceAfter - balanceBefore;

这些不是可选的重构。它们是协议正确性的生存要求。AI就是看不到它们。

6、前端的对账混乱

复杂性不会在EVM边界处停止。在跨链系统中,前端不仅仅是一个闪亮的表现层。它是一个疯狂的状态对账引擎。它必须追踪跨链的交易生命周期,而没有任何确定性的完成保证。我必须显式地建模:

type CrossChainTxState =
    | { status: "INITIATED"; txHash: string }
    | { status: "SOURCE_CONFIRMED"; blockNumber: number }
    | { status: "MESSAGE_DISPATCHED"; messageId: string }
    | { status: "IN_FLIGHT"; relayer: string }
    | { status: "DEST_EXECUTED"; destTxHash: string }
    | { status: "FAILED"; reason: string };

我最终构建了一个强大的轮询装置来查询源链、中继器和目标链,只是为了防止UI在飞行中继期间对用户撒谎:

async function trackCrossChainTx(txHash: string) {
    const sourceTx = await sourceProvider.getTransactionReceipt(txHash);
    if (!sourceTx) return { status: "INITIATED" };

    const messageId = extractMessageId(sourceTx.logs);
    const relayStatus = await relayerApi.getStatus(messageId);

    if (relayStatus === "PENDING") {
        return { status: "IN_FLIGHT" };
    }

    if (relayStatus === "DELIVERED") {
        const destTx = await destProvider.getTransaction(relayStatus.destTxHash);
        return { status: "DEST_EXECUTED", destTxHash: destTx.hash };
    }

    return { status: "FAILED", reason: relayStatus.error };
}

如果你搞错了这个分布式状态追踪,你会瞬间失去用户信任,无论你的智能合约多么完美。

7、安全需要意图

归根结底,安全需要对抗性意图。AI可以给你一个完美的重放保护修饰符。

mapping(bytes32 => bool) public executed;

function execute(bytes32 txId) external {
    require(!executed[txId], "Replay detected");
    executed[txId] = true;
}

实现很简单,但AI根本不知道这个模式应该放在哪里。识别跨合约边界的攻击面以及推理信任假设仍然完全是人类的工作。AI减少了产生工作代码的时间,但它没有减少让代码可靠所需的哪怕一分钟时间。

8、我的收获:向系统架构师的转变

当我终于在那艰苦的18小时冲刺后离开我的IDE时,我带着一个来之不易的教训离开。这个实验证明,我们的工作正在深刻改变。AI消除了编写代码的摩擦,但它极大地放大了系统设计的重要性。

我的角色从"逻辑实现者"大幅转变为"系统架构师"。我不再只是在写代码了。我在积极验证假设,并在能够打字快但无法提前思考的机器上强制执行架构边界。如果你在DeFi或任何高风险分布式环境中构建,AI会让你变得更快。但正确性的负担仍然完全落在你肩上。


原文链接: From 150 Hours to 18: How AI Helped Me Build a Cross-Chain DeFi Protocol 8x Faster

DefiPlot翻译整理,转载请标明出处

免责声明:本站资源仅用于学习目的,也不应被视为投资建议,读者在采取任何行动之前应自行研究并对自己的决定承担全部责任。