Intent Economy 實用開發指南:從 ERC-7683 到 Solver Network 的完整實作

本文深入探討 Intent Economy 的實用開發方法,從 ERC-7683 標準詳解到 Solver Network 架構設計,提供完整的 Solidity 和 Python 程式碼範例。涵蓋用戶 Intent 解析、荷蘭拍賣競標機制、跨鏈 Intent 實現、MEV 保護策略等核心主題。專為工程師設計的實務指南,幫助讀者從零開始構建完整的 Intent DApp。

Intent Economy 實用開發指南:從 ERC-7683 到 Solver Network 的完整實作

概述

我得坦白說,2024 年底的時候,我第一次看到「Intent」這個詞,心裡想的是「又是一個新概念,割韭菜用的吧」。結果 2025 年一整年看下來,我承認我錯了——Intent Economy 真的是個有實質意義的技術範式轉移,不只是行銷術語。

這篇文章我打算把 Intent Economy 從頭到尾捋一遍,目標讀者是工程師。想看理論的話,網上已經有一堆文章了,我這裡專注於實作——怎麼用 ERC-7683 建構 Solver Network、怎麼實現跨鏈意圖、怎麼處理 MEV 問題。


TL;DR(急著上工的工程師看這裡)

Intent 到底是什麼?

傳統方式:用戶說「我要做什麼」
Intent 方式:用戶說「我要什麼結果」

實例對比:

❌ 傳統:用戶操作 Uniswap,把 ETH 換成 USDC,設定滑點 0.5%,gas 上限 50 gwei

✅ Intent:用戶說「我想用不超過 2000 USDC 買 ETH,越便宜越好」

好處:
1. 用戶不用懂區塊鏈細節
2. Solver 幫你優化執行
3. 可以跨多個 DEX、跨多條鏈統一報價

壞處:
1. 需要信任 Solver
2. 複雜度增加
3. 還是會被 MEV 吃

一、Intent 的基本概念

1.1 從「操作」到「意圖」的範式轉移

先說個我自己的體會。我第一次用以太坊的時候,光是搞懂「gas」、「gwei」、「滑點」這些概念就折騰了半天。更別說後來 Layer2 出來,還有各種跨鏈橋、橋接代幣之類的爛攤子。

Intent 的出現,就是為了解決這個問題。

傳統 UX vs Intent-based UX:

傳統方式:
用戶 → 選擇 DEX → 設置參數 → 提交交易 → 等待確認 → 處理失敗

Intent 方式:
用戶 → 描述意圖 → 等待最優報價 → 自動執行 → 看到結果

區塊鏈複雜度被封裝在 Solver 這一層

1.2 Intent 的數學表示

把用戶的意圖形式化,能幫我們更好地理解系統:

定義 1.2.1(用戶 Intent):

一個 Intent I 是用戶對系統狀態的願望描述,包含:

I = (Constraint, Objective)

Constraint:必須滿足的約束條件
  - 交易對
  - 數量限制
  - 時間窗口
  - 鏈 / 網路限制

Objective:用戶的優化目標
  - 最小化費用
  - 最大化收到的代幣數量
  - 最小化滑點
定義 1.2.2(Intent 解析):

Solver S 收到 Intent I 後,生成執行計劃 P

S(I) → P

其中 P 是一系列原子操作
P = {op₁, op₂, ..., opₙ}

約束滿足:
∀ c ∈ Constraint(I): c(P) = true

1.3 Intent 的類型

不同類型的 Intent 有不同的複雜度和應用場景:

Intent 類型分類:

┌─────────────────────────────────────────────────────────────┐
│ Type 1:交換意圖(Swap Intent)                            │
├─────────────────────────────────────────────────────────────┤
│ 最簡單的 Intent 類型                                        │
│                                                             │
│ Example:                                                   │
│ 「我想用 1000 USDC 換盡可能多的 ETH」                       │
│                                                             │
│ 約束:input_amount ≤ 1000 USDC                              │
│ 目標:maximize output_amount                                │
│                                                             │
│ Solver 可以:                                               │
│ - 比較 Uniswap、Curve、SushiSwap 的報價                     │
│ - 計算最優分割(50% Uniswap + 50% Curve)                  │
│ - 執行時間優化(避開高 gas 時段)                          │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ Type 2:跨鏈意圖(Cross-chain Intent)                     │
├─────────────────────────────────────────────────────────────┤
│ 複雜度更高,涉及多條區塊鏈                                  │
│                                                             │
│ Example:                                                   │
│ 「我想從以太坊轉 1 ETH 到 Arbitrum,費用不超過 0.01 ETH」  │
│                                                             │
│ 約束:                                                      │
│ - 源鏈:Ethereum                                            │
│ - 目標鏈:Arbitrum                                          │
│ - 預算:≤ 0.01 ETH                                         │
│ - 時間:< 30 分鐘                                           │
│                                                             │
│ Solver 需要:                                               │
│ - 評估各橋的報價和可靠性                                    │
│ - 計算最優路由                                              │
│ - 管理跨鏈流動性                                            │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ Type 3:條件意圖(Conditional Intent)                     │
├─────────────────────────────────────────────────────────────┤
│ 最複雜的類型,涉及外部觸發條件                              │
│                                                             │
│ Example:                                                   │
│ 「如果 ETH 價格跌破 2000 USD,自動把我的 ERC-20 換成 ETH」  │
│                                                             │
│ 約束:                                                      │
│ - 觸發條件:Chainlink ETH/USD < 2000                       │
│ - 執行:swap to ETH                                        │
│ - 有效期:48 小時                                          │
│                                                             │
│ Solver 需要:                                              │
│ - 持續監控 Chainlink 數據源                                 │
│ - 等待觸發條件滿足                                         │
│ - 執行 swap 並記錄觸發條件                                 │
└─────────────────────────────────────────────────────────────┘

二、ERC-7683 標準詳解

2.1 為什麼需要 ERC-7683?

在 ERC-7683 出來之前,各種 Intent 系統都是各自為戰:

好處是各自優化,壞處是流動性碎片化、跨系統協作困難。

ERC-7683 的目標是:定義一個統一的 Intent 交換標準

ERC-7683 的核心思想:

┌─────────────────────────────────────────────────────────────┐
│                        ERC-7683 架構                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   用戶 Intent ──→│ 統一的 Intent 格式 │──→ Solver Network   │
│                  │  (ERC-7683)       │                      │
│                  │                    │                      │
│                  │  I = {            │                      │
│                  │    inputToken,   │                      │
│                  │    inputAmount,  │                      │
│                  │    outputToken,  │                      │
│                  │    minOutputAmount│                      │
│                  │    destinationChain│                      │
│                  │    receiver       │                      │
│                  │  }               │                      │
│                  └────────────────────┘                      │
│                              │                              │
│                              ▼                              │
│                  ┌─────────────────────────────────────┐   │
│                  │        Fill Data (由 Solver 填寫)    │   │
│                  │                                        │   │
│                  │  solver, fillTarget, observationNonce │   │
│                  │  version, reserved: bytes32           │   │
│                  └─────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2.2 ERC-7683 介面定義

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

/**
 * @title ERC-7683: Cross Chain Intent Standard
 * @notice 定義跨鏈 Intent 的標準格式
 * @dev 這個標準讓不同的 Intent 系統可以互相操作
 */
interface IERC7683 {
    /**
     * @notice 用戶的 Intent 結構
     * @param inputToken 用戶提供的輸入代幣地址
     * @param inputAmount 用戶提供的輸入代幣數量(不含小數位)
     * @param outputToken 用戶期望收到的輸出代幣地址
     * @param minOutputAmount 用戶可接受的最小輸出數量
     * @param destinationChain 用戶期望執行的目標鏈 ID
     * @param receiver 最終接收代幣的地址
     * @param sender 用戶的地址(Intent 簽名者)
     * @param nonce 用於防止重放的遞增數字
     * @param deadline Intent 的有效期
     * @param fillDeadline 用戶願意等待的最晚執行時間
     */
    struct Intent {
        address inputToken;
        uint256 inputAmount;
        address outputToken;
        uint256 minOutputAmount;
        uint256 destinationChain;
        address receiver;
        address sender;
        uint256 nonce;
        uint256 deadline;
        uint256 fillDeadline;
    }

    /**
     * @notice Solver 填寫的執行數據
     * @param solver Solver 的地址
     * @param fillTarget 實際執行交易的合約地址
     * @param observationNonce 用於 Solver 排序的 nonce
     * @param version 協議版本號
     * @param reserved 預留字段,未來擴展用
     */
    struct FillData {
        address solver;
        address fillTarget;
        uint256 observationNonce;
        uint128 version;
        bytes32 reserved;
    }

    /**
     * @notice 解析 Intent 並返回 FillData
     * @param intent 用戶的 Intent
     * @param signature 用戶的簽名
     * @return intentHash Intent 的哈希值
     * @return fillData 由 Solver 填寫的執行數據
     */
    function resolveIntent(
        Intent calldata intent,
        bytes calldata signature
    ) external returns (bytes32 intentHash, FillData memory fillData);
}

2.3 實際合約實現

讓我展示一個簡化的 ERC-7683 實現:

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

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title ERC7683Swap 实现
 * @dev 简化的 ERC-7683 Swap Intent 执行合約
 */
contract ERC7683Swap is ReentrancyGuard, Ownable {
    using SafeERC20 for IERC20;

    // 事件:記錄 Intent 被解決
    event IntentResolved(
        bytes32 indexed intentHash,
        address indexed solver,
        address indexed user,
        uint256 inputAmount,
        uint256 outputAmount
    );

    // 用戶的 nonce 映射,防止重放
    mapping(address => uint256) public nonces;

    // Solver 白名單
    mapping(address => bool) public authorizedSolvers;

    // Intent 解析器地址
    address public intentResolver;

    constructor(address _intentResolver) Ownable(msg.sender) {
        intentResolver = _intentResolver;
    }

    /**
     * @notice 解決用戶的 Swap Intent
     * @param intent 用戶的 Intent
     * @param signature 用戶的 EIP-712 簽名
     * @param fillData 由 Solver 填寫的數據
     */
    function resolveIntent(
        Intent calldata intent,
        bytes calldata signature,
        FillData calldata fillData
    ) external nonReentrant returns (bytes32) {
        // 1. 驗證簽名
        bytes32 intentHash = _verifySignature(intent, signature);
        
        // 2. 檢查 Solver 授權
        require(
            authorizedSolvers[fillData.solver],
            "Unauthorized solver"
        );
        
        // 3. 檢查 Intent 有效期
        require(
            block.timestamp <= intent.deadline,
            "Intent expired"
        );
        require(
            block.timestamp <= intent.fillDeadline,
            "Fill deadline passed"
        );
        
        // 4. 檢查 nonce(防止重放)
        require(
            intent.nonce == nonces[intent.sender],
            "Invalid nonce"
        );
        
        // 5. 轉移用戶的輸入代幣
        IERC20(intent.inputToken).safeTransferFrom(
            intent.sender,
            address(this),
            intent.inputAmount
        );
        
        // 6. 執行交換(這裡是簡化版,實際需要調用 DEX)
        uint256 outputAmount = _executeSwap(
            intent.inputToken,
            intent.outputToken,
            intent.inputAmount
        );
        
        // 7. 檢查最小輸出
        require(
            outputAmount >= intent.minOutputAmount,
            "Slippage exceeded"
        );
        
        // 8. 轉移輸出代幣給 receiver
        IERC20(intent.outputToken).safeTransfer(
            intent.receiver,
            outputAmount
        );
        
        // 9. 增加 nonce
        nonces[intent.sender]++;
        
        // 10. 發放獎勵給 Solver
        _paySolverReward(fillData.solver, intent.inputToken);
        
        emit IntentResolved(
            intentHash,
            fillData.solver,
            intent.sender,
            intent.inputAmount,
            outputAmount
        );
        
        return intentHash;
    }

    /**
     * @notice EIP-712 簽名驗證
     */
    function _verifySignature(
        Intent calldata intent,
        bytes calldata signature
    ) internal view returns (bytes32) {
        bytes32 domainSeparator = keccak256(
            abi.encode(
                keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                keccak256("ERC7683Swap"),
                keccak256("1"),
                block.chainid,
                address(this)
            )
        );
        
        bytes32 structHash = keccak256(
            abi.encode(
                keccak256("Intent(...)"),
                intent.inputToken,
                intent.inputAmount,
                intent.outputToken,
                intent.minOutputAmount,
                intent.destinationChain,
                intent.receiver,
                intent.sender,
                intent.nonce,
                intent.deadline,
                intent.fillDeadline
            )
        );
        
        bytes32 digest = keccak256(
            abi.encodePacked("\x19\x01", domainSeparator, structHash)
        );
        
        // 驗證簽名
        require(
            digest.recover(signature) == intent.sender,
            "Invalid signature"
        );
        
        return digest;
    }

    /**
     * @notice 執行交換(實際項目中需要接入 DEX)
     */
    function _executeSwap(
        address inputToken,
        address outputToken,
        uint256 inputAmount
    ) internal virtual returns (uint256 outputAmount) {
        // 這裡應該接入 Uniswap、Curve 等 DEX
        // 為了演示,返回簡化的輸出
        // 實際項目中需要調用真實的 DEX 合約
        outputAmount = inputAmount; // 1:1 簡化
        return outputAmount;
    }

    /**
     * @notice 向 Solver 支付獎勵
     */
    function _paySolverReward(address solver, address token) internal {
        // Solver 獎勵 = 節省的 gas + 執行費用
        // 實際實現中需要計算具體金額
    }

    /**
     * @notice 添加授權的 Solver
     */
    function addSolver(address solver) external onlyOwner {
        authorizedSolvers[solver] = true;
    }

    /**
     * @notice 移除 Solver
     */
    function removeSolver(address solver) external onlyOwner {
        authorizedSolvers[solver] = false;
    }
}

三、Solver Network 架構

3.1 Solver 的角色

Solver 是整個 Intent Economy 的核心。他們負責:

  1. 接收用戶的 Intent
  2. 計算最優執行路徑
  3. 競標執行權
  4. 執行交易並承擔 MEV
Solver 工作流程:

┌─────────────────────────────────────────────────────────────┐
│                    Solver Network                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 監控 Intent 發布                                        │
│     ┌─────────────────────────────────────────────────┐    │
│     │  Intent Auction (荷蘭式拍賣)                      │    │
│     │                                                  │    │
│     │  初始報價:$0.10                                 │    │
│     │  時間 →  價格 ↓                                  │    │
│     │                                                  │    │
│     │  Solver A: $0.05 (願意少賺)                     │    │
│     │  Solver B: $0.07                                │    │
│     │  Solver C: $0.06                                │    │
│     │                                                  │    │
│     │  Winner: Solver A                               │    │
│     └─────────────────────────────────────────────────┘    │
│                                                             │
│  2. 計算最優路徑                                            │
│     - DEX 報價聚合                                          │
│     - 路由優化                                              │
│     - 跨鏈橋費用估算                                        │
│                                                             │
│  3. 執行交易                                                │
│     - 提交到區塊鏈                                          │
│     - 處理失敗情況                                          │
│     - 結算給用戶                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

3.2 Solver 策略引擎實現

讓我展示一個簡化的 Solver 策略引擎:

"""
Solver 策略引擎
用於計算最優執行路徑
"""

from dataclasses import dataclass
from typing import List, Dict, Optional
from decimal import Decimal
import heapq

@dataclass
class SwapQuote:
    """交換報價"""
    dex_name: str
    input_token: str
    output_token: str
    input_amount: int
    output_amount: int
    price_impact: float
    gas_cost_wei: int
    
    def effective_output(self) -> int:
        """扣除 gas 成本後的有效輸出"""
        # 簡化計算:gas 成本轉換為 output token
        return self.output_amount

@dataclass
class ExecutionPath:
    """執行路徑"""
    steps: List[SwapQuote]
    total_input: int
    total_output: int
    total_gas: int
    
    def net_output(self) -> int:
        """淨輸出(扣除所有成本)"""
        return self.total_output

class SolverStrategy:
    """Solver 策略引擎"""
    
    def __init__(self, dex_registry: Dict):
        self.dex_registry = dex_registry
    
    def compute_optimal_path(
        self,
        input_token: str,
        output_token: str,
        input_amount: int,
        chains: List[int],
        deadline: int
    ) -> ExecutionPath:
        """計算最優執行路徑"""
        
        # 1. 獲取所有 DEX 的報價
        quotes = self._get_all_quotes(
            input_token,
            output_token,
            input_amount,
            chains
        )
        
        # 2. 單一跳轉 vs 多跳
        single_hop = self._find_best_single_hop(quotes)
        multi_hop = self._find_best_multi_hop(quotes, output_token)
        
        # 3. 返回最優路徑
        if single_hop and multi_hop:
            return max(single_hop, multi_hop, key=lambda p: p.net_output())
        return single_hop or multi_hop
    
    def _get_all_quotes(
        self,
        input_token: str,
        output_token: str,
        amount: int,
        chains: List[int]
    ) -> List[SwapQuote]:
        """從所有 DEX 獲取報價"""
        quotes = []
        
        for chain_id in chains:
            for dex_name, dex_address in self.dex_registry.get(chain_id, {}).items():
                quote = self._query_dex(
                    dex_name,
                    dex_address,
                    input_token,
                    output_token,
                    amount
                )
                if quote:
                    quotes.append(quote)
        
        return quotes
    
    def _find_best_single_hop(
        self,
        quotes: List[SwapQuote]
    ) -> Optional[ExecutionPath]:
        """找到最佳單跳路徑"""
        if not quotes:
            return None
        
        best = max(quotes, key=lambda q: q.effective_output())
        return ExecutionPath(
            steps=[best],
            total_input=best.input_amount,
            total_output=best.output_amount,
            total_gas=best.gas_cost_wei
        )
    
    def _find_best_multi_hop(
        self,
        quotes: List[SwapQuote],
        target_token: str
    ) -> Optional[ExecutionPath]:
        """找到最佳多跳路徑(貪心算法)"""
        # 簡化的多跳實現
        # 實際需要更複雜的 Dijkstra 或 A* 算法
        
        # 這裡用貪心:每次選擇當前最優的報價
        return None
    
    def _query_dex(
        self,
        dex_name: str,
        dex_address: str,
        input_token: str,
        output_token: str,
        amount: int
    ) -> Optional[SwapQuote]:
        """查詢單個 DEX 的報價"""
        # 實際實現中需要:
        # 1. 構建函數調用
        # 2. 估計 gas 消耗
        # 3. 計算 price impact
        # 這裡返回模擬數據
        pass

3.3 Solver 的 MEV 處理

MEV(最大可提取價值)是 Solver 必須面對的問題。

MEV 來源:

┌─────────────────────────────────────────────────────────────┐
│                    MEV 類型                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. Sandwich Attack(三角套利)                            │
│     - 在用戶交易前插入交易,拉高價格                        │
│     - 執行用戶交易                                          │
│     - 在用戶交易後賣出,獲取差價                            │
│                                                             │
│     受害者:普通 swap 用戶                                  │
│     頻率:常見                                              │
│                                                             │
│  2. Liquidation(清算)                                   │
│     - 監控清算機會                                          │
│     - 搶在其他清算者之前執行                                │
│                                                             │
│     受害者:借貸協議                                        │
│     頻率:取決於市場波動                                    │
│                                                             │
│  3. Arbitrage(套利)                                      │
│     - 不同 DEX 之間的價格差異                              │
│     - 同一 DEX 不同池之間                                  │
│                                                             │
│     受害者:無直接受害者                                    │
│     頻率:非常常見                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Solver 如何處理 MEV?

"""
MEV 保護策略
"""

class MEVProtection:
    """MEV 保護機制"""
    
    def __init__(self, flashbots_client):
        self.flashbots = flashbots_client
    
    def protected_bundle(
        self,
        user_intent: dict,
        solver_tx: dict
    ) -> dict:
        """使用 Flashbots Bundle 來隱藏交易"""
        
        bundle = {
            "jsonrpc": "2.0",
            "id": 1,
            "method": "eth_sendBundle",
            "params": [{
                "txs": [
                    solver_tx,  # Solver 的交易
                    # 沒有其他交易在旁邊
                ],
                "blockNumber": hex(current_block),
                "minTimestamp": user_intent.deadline,
                "maxTimestamp": user_intent.deadline + 60,
            }]
        }
        
        # 發送到 Flashbots Relay
        return self.flashbots.send(bundle)
    
    def detect_sandwich(self, pending_txs: list) -> bool:
        """檢測是否有 sandwich 攻擊"""
        
        for tx in pending_txs:
            if self._is_same_pair(tx, self.user_tx):
                if tx.gas_price > self.user_tx.gas_price:
                    # 這筆交易在我們之前,價格更高
                    # 可能是 sandwich 的第一步
                    return True
                    
        return False

四、跨鏈 Intent 實現

4.1 跨鏈 Intent 的挑戰

跨鏈 Intent 比單鏈 Intent 複雜得多:

跨鏈挑戰:

1. 橋接延遲
   - 用戶的輸入代幣在源鏈
   - 輸出代幣需要在目標鏈交付
   - 橋接需要時間(可能 10 分鐘到 30 分鐘)

2. 最終性問題
   - 不同鏈有不同的最終性
   - 以太坊:~12 分鐘(PoW)或 2 epochs(PoS)
   - Optimistic Rollup:7 天爭議期
   - ZK Rollup:幾分鐘到幾十分鐘

3. 流動性碎片化
   - 跨鏈橋的流動性分散
   - 同一資產在不同鏈上的價格可能不同
   - 需要考慮匯率風險

4. 結算貨幣
   - Solver 在哪條鏈上收到費用?
   - 如何解決跨鏈支付的問題?

4.2 跨鏈 Intent 合約實現

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

/**
 * @title CrossChainIntent
 * @dev 跨鏈 Intent 實現
 */
contract CrossChainIntent {
    
    // 橋接配置
    struct BridgeConfig {
        address bridgeAddress;
        uint256 destinationChainId;
        uint256 estimatedTime;      // 預估橋接時間
        uint256 maxSlippage;          // 最大滑點
    }
    
    // 跨鏈 Intent 數據
    struct CrossChainIntentData {
        address inputToken;
        uint256 inputAmount;
        address outputToken;
        uint256 minOutputAmount;
        uint256 destinationChain;
        address receiver;
        uint256 sourceDeadline;       // 源鏈 deadline
        uint256 fillDeadline;         // 跨鏈完成 deadline
    }
    
    // 已註冊的橋
    mapping(uint256 => BridgeConfig) public bridges;
    
    // 用戶的 active intents
    mapping(bytes32 => CrossChainIntentData) public activeIntents;
    
    // Solver 質押
    mapping(address => uint256) public solverBonds;
    
    // 事件
    event CrossChainIntentCreated(
        bytes32 indexed intentHash,
        address indexed sender,
        uint256 destinationChain,
        uint256 amount
    );
    
    event CrossChainIntentFilled(
        bytes32 indexed intentHash,
        address indexed solver,
        bytes32 sourceTxHash,
        uint256 outputAmount
    );
    
    /**
     * @notice 創建跨鏈 Intent
     */
    function createCrossChainIntent(
        CrossChainIntentData calldata intent
    ) external payable returns (bytes32) {
        // 1. 驗證參數
        require(
            intent.destinationChain != block.chainid,
            "Same chain"
        );
        require(
            intent.inputAmount > 0,
            "Zero amount"
        );
        
        // 2. 生成 intent hash
        bytes32 intentHash = keccak256(
            abi.encode(
                intent,
                msg.sender,
                nonces[msg.sender]++
            )
        );
        
        // 3. 轉移用戶的輸入代幣
        if (intent.inputToken == address(0)) {
            // ETH
            require(
                msg.value >= intent.inputAmount,
                "Insufficient ETH"
            );
        } else {
            IERC20(intent.inputToken).safeTransferFrom(
                msg.sender,
                address(this),
                intent.inputAmount
            );
        }
        
        // 4. 存儲 intent
        activeIntents[intentHash] = intent;
        
        emit CrossChainIntentCreated(
            intentHash,
            msg.sender,
            intent.destinationChain,
            intent.inputAmount
        );
        
        return intentHash;
    }
    
    /**
     * @notice Solver 填寫跨鏈 Intent
     */
    function fillCrossChainIntent(
        bytes32 intentHash,
        bytes32[] calldata bridgeTxHashes
    ) external {
        // 1. 獲取 intent
        CrossChainIntentData memory intent = activeIntents[intentHash];
        require(
            intent.receiver != address(0),
            "Intent not found"
        );
        
        // 2. 驗證 Solver 質押
        require(
            solverBonds[msg.sender] >= MIN_BOND,
            "Insufficient bond"
        );
        
        // 3. 驗證跨鏈交易
        uint256 receivedAmount = _verifyBridgeTransactions(
            intent.destinationChain,
            bridgeTxHashes
        );
        
        // 4. 檢查最小輸出
        require(
            receivedAmount >= intent.minOutputAmount,
            "Below minimum"
        );
        
        // 5. 轉移輸出代幣給 receiver
        if (intent.outputToken == address(0)) {
            (bool success, ) = intent.receiver.call{value: receivedAmount}("");
            require(success, "ETH transfer failed");
        } else {
            IERC20(intent.outputToken).safeTransfer(
                intent.receiver,
                receivedAmount
            );
        }
        
        // 6. 發放獎勵給 Solver
        _settleSolverReward(intentHash, msg.sender, intent.inputToken);
        
        // 7. 刪除 intent
        delete activeIntents[intentHash];
        
        emit CrossChainIntentFilled(
            intentHash,
            msg.sender,
            bridgeTxHashes[0],
            receivedAmount
        );
    }
    
    /**
     * @notice 驗證橋接交易
     */
    function _verifyBridgeTransactions(
        uint256 destChain,
        bytes32[] calldata txHashes
    ) internal view returns (uint256) {
        // 實際實現需要:
        // 1. 跨鏈消息驗證(LayerZero, Hyperlane 等)
        // 2. 金額驗證
        // 3. 接收方驗證
        // 這裡返回簡化結果
        BridgeConfig memory config = bridges[destChain];
        return config.estimatedTime; // 模擬
    }
}

五、實戰:構建一個完整的 Intent DApp

5.1 系統架構

┌─────────────────────────────────────────────────────────────┐
│                    Intent DApp 架構                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  前端(Next.js)                                            │
│  ├── Intent 表單                                            │
│  ├── 錢包連接(WalletConnect)                              │
│  └── 交易歷史                                               │
│                                                             │
│  智能合約(Solidity)                                       │
│  ├── IntentRegistry:Intent 註冊                           │
│  ├── IntentSolver:Solver 接口                             │
│  └── TokenVault:資金托管                                   │
│                                                             │
│  後端(Node.js)                                            │
│  ├── Intent Fulfiller:監控並填寫 Intent                   │
│  ├── Price Oracle:實時報價                                │
│  └── MEV Service:Flashbots 集成                           │
│                                                             │
│  Solver Network(獨立服務)                                 │
│  ├── Quote Engine:報價引擎                                │
│  ├── Route Optimizer:路徑優化                            │
│  └── Execution Engine:執行引擎                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

5.2 前端實現

// intent-dapp/hooks/useIntent.ts

import { useState, useCallback } from 'react';
import { useContractWrite, usePrepareContractWrite } from 'wagmi';
import { parseEther } from 'viem';
import { ERC7683_ABI } from '../abi/erc7683';

export function useIntent() {
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<Error | null>(null);

  const { config } = usePrepareContractWrite({
    address: PROCESS_ENV.NEXT_PUBLIC_INTENT_REGISTRY,
    abi: ERC7683_ABI,
    functionName: 'createIntent',
    args: [
      {
        inputToken: '0x...', // USDC address
        inputAmount: parseEther('1000'),
        outputToken: '0x...', // WETH address
        minOutputAmount: parseEther('0.5'),
        destinationChain: 42161, // Arbitrum
        receiver: userAddress,
        deadline: BigInt(Math.floor(Date.now() / 1000) + 3600),
        fillDeadline: BigInt(Math.floor(Date.now() / 1000) + 7200),
      }
    ],
  });

  const { writeAsync: createIntent } = useContractWrite(config);

  const submitIntent = useCallback(async () => {
    setIsLoading(true);
    setError(null);
    
    try {
      // 1. 構建 Intent
      const intent = {
        inputToken: inputTokenAddress,
        inputAmount: inputAmountWei,
        outputToken: outputTokenAddress,
        minOutputAmount: minOutputWei,
        destinationChain: destinationChainId,
        receiver: userAddress,
        deadline: deadlineTimestamp,
        fillDeadline: fillDeadlineTimestamp,
      };

      // 2. 簽名
      const signature = await signIntent(intent);

      // 3. 發送交易
      const tx = await createIntent?.();

      // 4. 等待確認
      const receipt = await tx.wait();

      // 5. 返回結果
      return {
        success: true,
        txHash: receipt.transactionHash,
        intentHash: receipt.logs[0].args.intentHash,
      };
    } catch (err) {
      setError(err as Error);
      return { success: false, error: err };
    } finally {
      setIsLoading(false);
    }
  }, [createIntent]);

  return { submitIntent, isLoading, error };
}

5.3 Solver 後端實現

# solver/backend/intent_monitor.py

"""
Intent 監控和填寫服務
"""

import asyncio
import logging
from typing import Optional
from web3 import Web3
from dataclasses import dataclass

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@dataclass
class Intent:
    hash: bytes32
    input_token: str
    input_amount: int
    output_token: str
    min_output: int
    deadline: int
    fill_deadline: int
    sender: str
    receiver: str

class IntentSolver:
    def __init__(
        self,
        rpc_url: str,
        private_key: str,
        intent_registry: str,
        min_profit: int = 1000000000000000  # 0.001 ETH
    ):
        self.w3 = Web3(Web3.HTTPProvider(rpc_url))
        self.account = self.w3.eth.account.from_key(private_key)
        self.intent_registry = Web3.to_checksum_address(intent_registry)
        self.min_profit = min_profit
        
        # 設置默認帳戶
        self.w3.eth.default_account = self.account.address
        
    async def start(self):
        """啟動 Solver"""
        logger.info(f"Solver 啟動: {self.account.address}")
        
        # 監控新 Intent
        while True:
            try:
                await self._check_new_intents()
                await asyncio.sleep(5)  # 每 5 秒檢查一次
            except Exception as e:
                logger.error(f"Error: {e}")
                await asyncio.sleep(30)
    
    async def _check_new_intents(self):
        """檢查新的 Intents"""
        # 獲取新 Intent 的 event logs
        # 這裡需要根據具體合約實現
        pass
    
    async def _evaluate_intent(self, intent: Intent) -> Optional[dict]:
        """評估 Intent 是否值得執行"""
        
        # 1. 檢查截止時間
        if intent.deadline < asyncio.get_event_loop().time():
            return None
            
        # 2. 獲取當前報價
        quote = await self._get_quote(
            intent.input_token,
            intent.output_token,
            intent.input_amount
        )
        
        if not quote:
            return None
            
        # 3. 計算利潤
        profit = quote['output_amount'] - intent.min_output
        
        if profit < self.min_profit:
            return None
            
        # 4. 估算 gas
        gas_estimate = await self._estimate_gas(intent)
        gas_cost = gas_estimate * self.w3.eth.gas_price
        
        net_profit = profit - gas_cost
        
        if net_profit < self.min_profit:
            return None
            
        return {
            'intent_hash': intent.hash,
            'output_amount': quote['output_amount'],
            'gas_estimate': gas_estimate,
            'net_profit': net_profit,
            'route': quote['route']
        }
    
    async def _fill_intent(self, intent: Intent, fill_data: dict):
        """填寫 Intent"""
        
        try:
            # 1. 執行交換
            tx_hash = await self._execute_swap(fill_data['route'])
            
            # 2. 提交 fill proof 到合約
            fill_tx = self._build_fill_transaction(
                intent.hash,
                tx_hash
            )
            
            # 3. 簽名並發送
            signed = self.account.sign_transaction(fill_tx)
            tx = self.w3.eth.send_raw_transaction(signed.rawTransaction)
            
            # 4. 等待確認
            receipt = self.w3.eth.wait_for_transaction_receipt(tx)
            
            logger.info(f"Intent filled: {intent.hash.hex()}")
            return receipt
            
        except Exception as e:
            logger.error(f"Failed to fill intent: {e}")
            return None

六、結語:Intent Economy 的未來

6.1 當前的瓶頸

Intent Economy 目前面臨的問題:

1. 信任模型
   - 用戶需要信任 Solver
   - Solver 質押機制可以緩解,但不是萬能的
   - 需要更好的經濟安全性

2. 結算效率
   - 跨鏈 Intent 的結算時間很長
   - 用戶體驗受影響
   - 需要更好的橋接技術

3. MEV 問題
   - Solver 可以提取 MEV
   - 用戶最終收到的可能不是最優報價
   - 需要更好的 MEV 保護

4. 合規問題
   - Intent 可能被用於洗錢
   - Solver 需要 KYC/AML
   - 各國監管要求不同

6.2 未來的發展方向

幾個我比較看好的方向:

1. Intent 標準統一
   - ERC-7683 是第一步
   - 未來會有更多跨應用的標準

2. Solver 專業化
   - 專業的 Solver 提供更好的報價
   - 規模效應降低成本
   - 最終可能形成類似傳統金融的「做市商」生態

3. ZK 在 Intent 中的應用
   - 用 ZK 證明 Solver 的執行是正確的
   - 用戶可以驗證「沒有被坑」
   - 這會是 ZKML + Intent 的結合點

4. AI + Intent
   - AI Agent 使用 Intent 接口與區塊鏈交互
   - 用戶不再需要理解區塊鏈
   - 自然語言 → Intent → 執行

參考資源

資源連結說明
ERC-7683 提案https://eips.ethereum.org/EIPS/eip-7683標準定義
UniswapX 白皮書https://uniswap.org/whitepaper-v3.pdfSwap Intent 實現
CoW Protocolhttps://docs.cow.fi荷蘭拍賣模式
Flashbotshttps://docs.flashbots.netMEV 保護

免責聲明:本文僅供教育和技術參考。智能合約開發涉及高度風險,實際部署前請進行完整的安全審計。

延伸閱讀與來源

這篇文章對您有幫助嗎?

評論

發表評論

注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。

目前尚無評論,成為第一個發表評論的人吧!