Skip to content

Latest commit

 

History

History
638 lines (526 loc) · 19.7 KB

File metadata and controls

638 lines (526 loc) · 19.7 KB

Code Analysis | 代码分析

This document provides detailed analysis of core code implementations in the AI Smart Wallet project.

本文档详细分析 AI Smart Wallet 项目的核心代码实现。


1. Intent Parser Analysis | 意图解析器分析

Overview | 概述

The Intent Parser converts natural language commands into blockchain transaction parameters.

意图解析器将自然语言命令转换为区块链交易参数。

Core Implementation | 核心实现

// frontend/lib/intentParser.ts

/**
 * 解析后的意图结构
 * Parsed intent structure
 */
export interface ParsedIntent {
  target: `0x${string}`      // 交易目标地址 | Transaction target
  value: bigint              // ETH 数量 (wei) | ETH amount in wei
  data: `0x${string}`        // 调用数据 | Calldata
  description: string        // 意图描述 | Intent description
  suggestedModule?: `0x${string}`  // 建议的策略模块 | Suggested module
}

/**
 * 意图模式匹配规则
 * Intent pattern matching rules
 */
interface IntentPattern {
  type: IntentType
  patterns: RegExp[]
  extract: (match: RegExpMatchArray, input: string) => Partial<ParsedIntent> | null
}

Pattern Matching | 模式匹配

The parser uses regex patterns to identify intent types:

解析器使用正则表达式模式识别意图类型:

/**
 * ETH 转账模式
 * Supports formats:
 * - "转账 0.1 ETH 到 0x123..."
 * - "发送 1 ETH 给 0x456..."
 * - "transfer 0.5 ETH to 0x789..."
 * - "send 2 ETH to 0xabc..."
 */
const transferPattern: IntentPattern = {
  type: 'transfer',
  patterns: [
    /(?:||transfer|send)\s*([\d.]+)\s*(?:ETH|eth|ether)\s*(?:||to)\s*(0x[a-fA-F0-9]{40})/i,
  ],
  extract: (match) => {
    const amount = match[1]  // 捕获组1: 金额
    const target = match[2]  // 捕获组2: 地址
    
    if (!amount || !target) return null
    if (!isAddress(target)) return null  // 验证地址格式
    
    try {
      const value = parseEther(amount)  // 转换为 wei
      return {
        target: target as `0x${string}`,
        value,
        data: '0x' as `0x${string}`,
        description: `转账 ${amount} ETH 到 ${target}`,
      }
    } catch {
      return null  // 金额解析失败
    }
  },
}

Main Parse Function | 主解析函数

export function parseIntent(intent: string): IntentParseResult {
  // 1. 输入验证 | Input validation
  if (!intent || typeof intent !== 'string') {
    return { success: false, error: '意图不能为空' }
  }

  const trimmedIntent = intent.trim()
  if (trimmedIntent.length === 0) {
    return { success: false, error: '意图不能为空' }
  }

  // 2. 遍历所有模式 | Iterate through all patterns
  for (const pattern of intentPatterns) {
    for (const regex of pattern.patterns) {
      const match = trimmedIntent.match(regex)
      if (match) {
        // 3. 提取意图数据 | Extract intent data
        const extracted = pattern.extract(match, trimmedIntent)
        if (extracted && extracted.target && extracted.description) {
          return {
            success: true,
            intent: {
              target: extracted.target,
              value: extracted.value ?? BigInt(0),
              data: extracted.data ?? '0x' as `0x${string}`,
              description: extracted.description,
              suggestedModule: extracted.suggestedModule,
            },
          }
        }
      }
    }
  }

  // 4. 无法解析 | Unable to parse
  return {
    success: false,
    error: '无法解析意图。支持的格式:\n- 转账 [数量] ETH 到 [地址]\n- 调用 [合约地址]',
  }
}

Data Flow Diagram | 数据流图

┌─────────────────┐
│  User Input     │  "转账 0.1 ETH 到 0x1234..."
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Input Validate │  Check: non-empty string
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Pattern Match   │  Match against regex patterns
└────────┬────────┘
         │
    ┌────┴────┐
    │ Match?  │
    └────┬────┘
    Yes  │  No
    ▼    ▼
┌───────┐ ┌───────┐
│Extract│ │ Error │
└───┬───┘ └───────┘
    │
    ▼
┌─────────────────┐
│ Validate Data   │  isAddress(), parseEther()
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ ParsedIntent    │  { target, value, data, description }
└─────────────────┘

2. ZK Circuit Analysis | ZK 电路分析

Circuit Structure | 电路结构

// circuits/strategy.circom

template DailyLimitStrategy() {
    // ============================================
    // 私有输入 (Private Inputs) - 不公开
    // ============================================
    signal input dailyLimit;           // 每日限额
    signal input whitelist[5];         // 白名单地址
    signal input salt;                 // 随机盐值
    signal input whitelistEnabled;     // 白名单开关
    
    // ============================================
    // 公开输入 (Public Inputs) - 链上可见
    // ============================================
    signal input commitment;           // 策略承诺值
    signal input txValue;              // 交易金额
    signal input txTarget;             // 交易目标
    signal input dailySpent;           // 当日已花费
    
    // ============================================
    // 输出 (Output)
    // ============================================
    signal output valid;               // 验证结果
}

Constraint 1: Commitment Verification | 约束1:承诺值验证

// 使用 Poseidon 哈希生成承诺值
// Generate commitment using Poseidon hash
component hasher = Poseidon(8);
hasher.inputs[0] <== dailyLimit;
hasher.inputs[1] <== whitelist[0];
hasher.inputs[2] <== whitelist[1];
hasher.inputs[3] <== whitelist[2];
hasher.inputs[4] <== whitelist[3];
hasher.inputs[5] <== whitelist[4];
hasher.inputs[6] <== salt;
hasher.inputs[7] <== whitelistEnabled;

// 约束:计算的哈希必须等于公开的承诺值
// Constraint: computed hash must equal public commitment
signal commitmentMatch;
commitmentMatch <== hasher.out - commitment;
commitmentMatch === 0;  // 强制相等 | Force equality

Why Poseidon? | 为什么用 Poseidon?

  • ZK-friendly hash function | ZK 友好的哈希函数
  • ~300 constraints vs ~25,000 for SHA256 | 约 300 个约束 vs SHA256 的约 25,000 个
  • Native field arithmetic | 原生域运算

Constraint 2: Daily Limit Check | 约束2:每日限额检查

// 计算总花费 | Calculate total spending
signal totalSpending;
totalSpending <== dailySpent + txValue;

// 比较器:检查是否在限额内
// Comparator: check if within limit
component limitCheck = LessEqThan(252);  // 252-bit 比较
limitCheck.in[0] <== totalSpending;
limitCheck.in[1] <== dailyLimit;

signal withinLimit;
withinLimit <== limitCheck.out;  // 1 if within, 0 if exceeded

Mathematical Representation | 数学表示:

withinLimit = 1  iff  dailySpent + txValue ≤ dailyLimit

Constraint 3: Whitelist Check | 约束3:白名单检查

// 检查目标是否在白名单中
// Check if target is in whitelist
component isEqual[5];
signal matches[5];

for (var i = 0; i < 5; i++) {
    isEqual[i] = IsEqual();
    isEqual[i].in[0] <== txTarget;
    isEqual[i].in[1] <== whitelist[i];
    matches[i] <== isEqual[i].out;  // 1 if match, 0 otherwise
}

// OR 所有匹配结果 | OR all matches
// inWhitelist = matches[0] ∨ matches[1] ∨ ... ∨ matches[4]
signal orResult[4];

component or1 = OR();
or1.a <== matches[0];
or1.b <== matches[1];
orResult[0] <== or1.out;

// ... (继续 OR 链)

signal inWhitelist;
inWhitelist <== orResult[3];

// 条件检查:如果白名单禁用则跳过
// Conditional: bypass if whitelist disabled
signal whitelistValid;
signal whitelistEnabledTimesInWhitelist;
whitelistEnabledTimesInWhitelist <== whitelistEnabled * inWhitelist;
whitelistValid <== (1 - whitelistEnabled) + whitelistEnabledTimesInWhitelist;

Logic Table | 逻辑表:

whitelistEnabled inWhitelist whitelistValid
0 0 1 (bypass)
0 1 1 (bypass)
1 0 0 (reject)
1 1 1 (accept)

Final Output | 最终输出

// 两个条件都必须满足
// Both conditions must pass
valid <== withinLimit * whitelistValid;

3. Property-Based Testing Analysis | 属性测试分析

Testing Philosophy | 测试理念

Property-based testing verifies that properties hold for ALL valid inputs, not just specific examples.

属性测试验证属性对所有有效输入都成立,而不仅仅是特定示例。

Example: Intent Parser Properties | 示例:意图解析器属性

// frontend/lib/intentParser.property.test.ts

import { describe, it, expect } from 'vitest'
import * as fc from 'fast-check'
import { parseIntent, isValidParsedIntent } from './intentParser'

describe('Intent Parser Properties', () => {
  
  // Property 1: 有效转账意图总是能被解析
  // Valid transfer intents are always parseable
  it('should parse valid transfer intents', () => {
    fc.assert(
      fc.property(
        // 生成器:有效的 ETH 金额和地址
        // Generator: valid ETH amounts and addresses
        fc.float({ min: 0.001, max: 1000, noNaN: true }),
        fc.hexaString({ minLength: 40, maxLength: 40 }),
        (amount, addressHex) => {
          const address = `0x${addressHex}`
          const intent = `transfer ${amount} ETH to ${address}`
          const result = parseIntent(intent)
          
          // 属性:解析成功且目标地址正确
          // Property: parse succeeds and target is correct
          expect(result.success).toBe(true)
          expect(result.intent?.target.toLowerCase()).toBe(address.toLowerCase())
        }
      ),
      { numRuns: 100 }  // 运行 100 次随机测试
    )
  })

  // Property 2: 空输入总是返回错误
  // Empty inputs always return error
  it('should reject empty inputs', () => {
    fc.assert(
      fc.property(
        fc.constantFrom('', '   ', '\n', '\t'),
        (emptyInput) => {
          const result = parseIntent(emptyInput)
          expect(result.success).toBe(false)
          expect(result.error).toBeDefined()
        }
      )
    )
  })

  // Property 3: 解析结果的不变量
  // Invariants of parsed results
  it('should maintain parsed intent invariants', () => {
    fc.assert(
      fc.property(
        fc.float({ min: 0.001, max: 1000, noNaN: true }),
        fc.hexaString({ minLength: 40, maxLength: 40 }),
        (amount, addressHex) => {
          const address = `0x${addressHex}`
          const intent = `send ${amount} ETH to ${address}`
          const result = parseIntent(intent)
          
          if (result.success && result.intent) {
            // 不变量:value 是 bigint
            expect(typeof result.intent.value).toBe('bigint')
            // 不变量:value >= 0
            expect(result.intent.value >= 0n).toBe(true)
            // 不变量:data 以 0x 开头
            expect(result.intent.data.startsWith('0x')).toBe(true)
            // 不变量:description 非空
            expect(result.intent.description.length).toBeGreaterThan(0)
          }
        }
      )
    )
  })
})

Smart Contract Property Tests | 智能合约属性测试

// test/SmartWalletV2.property.test.cjs

const fc = require('fast-check')
const { expect } = require('chai')

describe('SmartWalletV2 Properties', function() {
  
  // Property: 守护者添加后状态一致
  // Guardian addition maintains state consistency
  it('guardian addition is consistent', async function() {
    await fc.assert(
      fc.asyncProperty(
        fc.array(fc.hexaString({ minLength: 40, maxLength: 40 }), { minLength: 1, maxLength: 5 }),
        async (guardianHexes) => {
          const guardians = guardianHexes.map(h => `0x${h}`)
          
          // 添加所有守护者
          for (const guardian of guardians) {
            await wallet.addGuardian(guardian)
          }
          
          // 属性:所有添加的守护者都应该是守护者
          for (const guardian of guardians) {
            const isGuardian = await wallet.isGuardian(guardian)
            expect(isGuardian).to.be.true
          }
          
          // 属性:守护者列表长度正确
          const list = await wallet.getGuardians()
          expect(list.length).to.equal(guardians.length)
        }
      ),
      { numRuns: 50 }
    )
  })

  // Property: 恢复阈值约束
  // Recovery threshold constraints
  it('threshold cannot exceed guardian count', async function() {
    await fc.assert(
      fc.asyncProperty(
        fc.integer({ min: 1, max: 10 }),
        fc.integer({ min: 1, max: 10 }),
        async (guardianCount, threshold) => {
          // 添加守护者
          for (let i = 0; i < guardianCount; i++) {
            await wallet.addGuardian(ethers.Wallet.createRandom().address)
          }
          
          if (threshold > guardianCount) {
            // 属性:阈值超过守护者数量应该失败
            await expect(
              wallet.setRecoveryThreshold(threshold)
            ).to.be.revertedWith('Threshold exceeds guardian count')
          } else {
            // 属性:有效阈值应该成功
            await wallet.setRecoveryThreshold(threshold)
            const currentThreshold = await wallet.getRecoveryThreshold()
            expect(currentThreshold).to.equal(threshold)
          }
        }
      )
    )
  })
})

4. ERC-7579 Module Integration | ERC-7579 模块集成

Module Interface | 模块接口

// contracts/interfaces/IStrategyModule.sol

interface IStrategyModule {
    /**
     * @notice 检查交易是否被允许
     * @param caller 调用者地址
     * @param target 目标地址
     * @param value ETH 数量
     * @param data 调用数据
     * @return allowed 是否允许
     */
    function check(
        address caller,
        address target,
        uint256 value,
        bytes calldata data
    ) external view returns (bool allowed);
    
    /**
     * @notice 返回模块名称
     */
    function name() external view returns (string memory);
}

Module Installation Flow | 模块安装流程

function installModule(
    uint256 moduleType,    // 模块类型 (ERC-7579 定义)
    address module,        // 模块地址
    bytes calldata initData // 初始化数据
) external onlyOwner {
    require(module != address(0), "Invalid module address");
    
    // 1. 注册模块
    modules[module] = true;
    
    // 2. 调用模块初始化(如果有)
    if (initData.length > 0) {
        (bool success,) = module.call(initData);
        require(success, "Module init failed");
    }
    
    // 3. 发出事件
    emit ModuleInstalled(moduleType, module);
}

Execution with Module | 带模块的执行

function executeWithModule(
    address target,
    uint256 value,
    bytes calldata data,
    address module
) external returns (bytes memory result) {
    // 1. 授权检查
    require(msg.sender == owner || agents[msg.sender], "Not authorized");
    
    // 2. 模块激活检查
    require(modules[module], "Module not active");
    
    // 3. 余额检查
    require(address(this).balance >= value, "Insufficient balance");
    
    // 4. 模块策略检查 ⭐
    bool allowed = IStrategyModule(module).check(msg.sender, target, value, data);
    require(allowed, "Module check failed");
    
    // 5. 执行交易
    bool success;
    (success, result) = target.call{value: value}(data);
    
    // 6. 发出事件
    emit Execution(target, value, data, success);
    
    return result;
}

5. State Machine Analysis | 状态机分析

Recovery State Machine | 恢复状态机

                    ┌─────────────────┐
                    │    INACTIVE     │
                    │  (No Recovery)  │
                    └────────┬────────┘
                             │
                             │ initiateRecovery()
                             │ [guardian calls]
                             ▼
                    ┌─────────────────┐
                    │     ACTIVE      │◄────────────┐
                    │  (Collecting    │             │
                    │   Supports)     │─────────────┤
                    └────────┬────────┘             │
                             │                      │
           ┌─────────────────┼─────────────────┐    │
           │                 │                 │    │
           │ cancelRecovery()│ supportRecovery()    │
           │ [owner calls]   │ [guardian calls]     │
           │                 │                      │
           ▼                 ▼                      │
    ┌──────────┐    ┌─────────────────┐            │
    │ INACTIVE │    │ supportCount++  │────────────┘
    └──────────┘    └────────┬────────┘
                             │
                             │ [supportCount >= threshold]
                             │
                             ▼
                    ┌─────────────────┐
                    │  executeRecovery│
                    │  [anyone calls] │
                    └────────┬────────┘
                             │
                             │ [within 7 days]
                             ▼
                    ┌─────────────────┐
                    │   COMPLETED     │
                    │ (Owner Changed) │
                    └─────────────────┘

State Transitions | 状态转换

Current State Action Condition Next State
INACTIVE initiateRecovery isGuardian ACTIVE
ACTIVE supportRecovery isGuardian, !alreadySupported ACTIVE
ACTIVE executeRecovery supportCount >= threshold, !expired COMPLETED
ACTIVE cancelRecovery isOwner INACTIVE
ACTIVE expireRecovery timestamp > initiatedAt + 7 days INACTIVE

Summary | 总结

This codebase demonstrates several advanced patterns:

本代码库展示了几个高级模式:

  1. Intent-Centric Design | 意图驱动设计

    • Natural language → Transaction parameters
    • 自然语言 → 交易参数
  2. Zero-Knowledge Privacy | 零知识隐私

    • Hide strategy details while proving compliance
    • 隐藏策略细节同时证明合规
  3. Modular Architecture | 模块化架构

    • ERC-7579 compatible pluggable modules
    • ERC-7579 兼容的可插拔模块
  4. Property-Based Testing | 属性测试

    • Verify invariants across all inputs
    • 验证所有输入的不变量
  5. Social Recovery | 社交恢复

    • Guardian-based ownership recovery
    • 基于守护者的所有权恢复