Skip to content

地址管理

PayIn 地址池系统中管理区块链地址的综合指南。

概述

PayIn 的地址池是一个复杂的地址管理系统,可以预生成并动态分配区块链地址用于支付处理。这种方法实现了:

  • 即时地址分配:无需按需生成地址
  • 地址可重用性:通过冷却保护实现高效回收
  • 多链支持:统一管理 EVM、Tron 和 Solana
  • 安全性:正确的密钥管理和地址隔离
  • 可扩展性:处理大量支付操作

为什么需要地址池?

传统支付系统按需生成地址,会造成延迟。PayIn 的地址池预先生成地址,实现即时支付地址分配,提升用户体验。

地址池概念

工作原理

┌─────────────────────────────────────────────────────────────┐
│                      地址池系统                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌──────────────┐  分配    ┌──────────────┐               │
│  │  可用地址    │  ────────→  │  已分配      │             │
│  │              │             │  (订单)      │             │
│  │              │             │              │             │
│  │  1000 地址   │  ←────────  │  50 地址     │             │
│  └──────────────┘   释放     └──────────────┘             │
│        ↑                                                    │
│        │                                                    │
│        │ 冷却后                                             │
│        │                                                    │
│  ┌──────────────┐             ┌──────────────┐             │
│  │  冷却中      │             │    已绑定    │             │
│  │  (30分钟)    │             │  (充值)      │             │
│  │              │             │              │             │
│  │  100 地址    │             │  200 地址    │             │
│  └──────────────┘             └──────────────┘             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

核心概念

  1. 预生成:地址在需要之前批量生成
  2. 动态分配:从池中按需分配地址
  3. 状态管理:地址通过定义的状态转换
  4. 自动回收:订单地址在完成后返回池中
  5. 冷却保护:防止立即重用,保护隐私和安全

地址状态

PayIn 通过四种状态管理地址:

状态描述用途返回池中
available(可用)准备分配在池中等待不适用
allocated(已分配)临时分配活跃订单是(完成后)
bound(已绑定)永久分配用户充值可选(手动解绑)
cooldown(冷却中)最近释放临时保留是(30分钟后)
状态转换图
               分配                  完成/过期
  available  ─────────→  allocated  ──────────────→  cooldown
      ↑                                                   │
      │                                                   │
      └───────────────── 30分钟后 ─────────────────────────┘

               绑定                      解绑
  available  ─────────→   bound    ─────────────→  cooldown
      ↑                                                   │
      │                                                   │
      └───────────────── 30分钟后 ─────────────────────────┘

为什么冷却很重要

冷却期(默认:30分钟)提供:

  1. 隐私保护:防止立即将不同订单链接到同一地址
  2. 结算窗口:为区块链最终确认留出时间
  3. 用户信心:避免地址重用造成的混淆
  4. 监控清理:确保监控任务正确完成

可配置的冷却期

冷却期可以通过 address_pool.cooldown_minutes 配置参数按组织调整。

地址管理模式

PayIn 支持两种地址管理方式,以适应不同的安全模型和操作偏好。

对比表

功能HD 钱包模式自管理模式
密钥管理用户控制助记词用户控制私钥
地址生成PayIn CLI 工具用户自己的工具
可追溯性完整(派生索引)有限
备份单个助记词每个密钥分别备份
工具PayIn 提供工具用户提供工具
推荐用于大多数用户高级用户
安全责任用户(助记词)用户(所有密钥)

推荐

我们强烈推荐大多数用例使用 HD 钱包模式。它提供更好的可追溯性、更简单的备份和 PayIn 的完整工具支持。

HD 钱包模式(推荐)

HD 钱包模式使用 BIP44 分层确定性钱包标准从单个主种子(助记词)派生地址。

优势

  • 单一备份:一个 12/24 词助记词备份无限地址
  • 确定性:可以使用助记词 + 派生索引重新生成任何地址
  • 完全可追溯:跟踪哪些地址属于您的钱包
  • PayIn 工具:完整的 CLI 工具支持生成和验证
  • 基于标准:使用行业标准 BIP44 路径

工作原理

  1. 生成 BIP39 助记词(12 或 24 个单词)
  2. 使用 PayIn 地址工具从助记词派生地址
  3. 导出地址到 CSV(包括派生索引)
  4. 通过 Admin UI 将 CSV 导入 PayIn
  5. PayIn 从池中分配地址

派生路径

EVM 链:    m/44'/60'/0'/0/{index}   (Ethereum, Polygon 等)
Tron 链:   m/44'/195'/0'/0/{index}
Solana 链: m/44'/501'/{index}'/0'   (强化派生)

Solana 限制

Solana 使用带强化派生的 Ed25519 加密(SLIP-0010),这意味着:

  • ❌ 无法从主公钥派生子地址
  • ✅ 地址生成需要完整助记词
  • ✅ 地址仍通过派生索引跟踪
  • ✅ 完全兼容 PayIn 的地址池

这是 Ed25519 的基本加密属性,不是 PayIn 的限制。

自管理模式

自管理模式允许您导入由自己的工具或钱包生成的地址。

优势

  • 完全控制:使用您喜欢的钱包软件
  • 灵活性:从任何来源导入地址
  • 自定义工作流:与现有密钥管理集成
  • 无派生:不绑定到任何特定派生方案

注意事项

  • ⚠️ 手动备份:必须分别备份每个地址/密钥
  • ⚠️ 有限可追溯性:PayIn 不知道地址关系
  • ⚠️ 您的责任:必须确保地址有效且安全

工作原理

  1. 使用钱包软件生成地址
  2. 导出为 CSV 格式
  3. 通过 Admin UI 或 API 将 CSV 导入 PayIn
  4. PayIn 从池中分配地址

CSV 格式

csv
address,protocol,derivation_index,master_public_key
0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0,evm,,
TYASr5UV6HEcXatwdFQfmLVUqQQQMUxHLS,tron,,

可选字段

对于自管理地址,derivation_indexmaster_public_key 是可选的。如果不适用,请留空。

HD 钱包地址生成

本节介绍使用 PayIn 官方工具在 HD 钱包模式下生成地址的完整工作流程。

前提条件

  1. 安全环境:使用离线计算机或气隙系统以获得最大安全性
  2. Node.js:18 或更高版本
  3. PayIn 地址工具:官方 CLI 工具
  4. 安全存储:助记词备份的物理位置(保险箱、金库等)

步骤 1:安装地址工具

bash
# 导航到 PayIn 仓库
cd payin/apps/address-tool

# 安装依赖
npm install

# 构建工具
npm run build

全局安装

为了更方便访问,您可以全局安装:

bash
npm install -g @payin/address-tool

然后运行:payin-address-tool

步骤 2:生成助记词

启动工具并选择生成新助记词:

bash
npm start

交互流程

? Select an action: Generate New Addresses
? Select protocol: EVM (Ethereum, Polygon, etc.)
? Do you have an existing mnemonic? No, generate new mnemonic

🔐 Your Mnemonic Phrase (WRITE THIS DOWN IMMEDIATELY!):

    witch collapse practice feed shame open despair creek road again ice least

⚠️  WARNING:
   - Write down this mnemonic on paper
   - Store it in a secure, offline location
   - Anyone with this phrase can access your funds
   - This tool does NOT save it for you

? Have you written down the mnemonic? (yes/no): yes

安全检查清单

  • ✅ 在纸上写下助记词(而非数字方式)
  • ✅ 仔细检查每个单词是否正确
  • ✅ 存储在安全位置(保险箱、银行保险箱)
  • ✅ 考虑在不同位置创建多个备份
  • ❌ 永远不要保存到计算机、手机或云存储
  • ❌ 永远不要拍摄助记词的照片
  • ❌ 永远不要与任何人分享

步骤 3:生成地址

配置地址生成参数:

? Starting derivation index: 0
? How many addresses to generate: 1000

Generating addresses...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% | 1000/1000

✅ Generated 1000 addresses successfully!

Protocol: evm
Derivation Path: m/44'/60'/0'/0/{index}
Range: 0 - 999

生成提示

  • 批量大小:每批生成 1000-5000 个地址
  • 起始索引:第一批使用 0,然后 1000、2000 等
  • 多协议:分别为 EVM、Tron 和 Solana 生成

步骤 4:导出到 CSV

? Export to CSV? Yes
? Output file name: evm-addresses-2025-01-20

Exporting to CSV...
✅ Exported to: output/evm-addresses-2025-01-20-full.csv

CSV Format: Full (HD Wallet Mode)
Columns: address, derivation_index, protocol, master_public_key
Rows: 1000

CSV 内容示例

csv
address,derivation_index,protocol,master_public_key
0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0,0,evm,xpub6CUGRUonZSQ4TWUJKy...
0x5AEDA56215b167893e80B4fE645BA6d5Bab767DE,1,evm,xpub6CUGRUonZSQ4TWUJKy...
0x9FF4e4b8a0451F7c8F7a1D8c1C6b5C2d3E4f5A6B,2,evm,xpub6CUGRUonZSQ4TWUJKy...

CSV 文件安全

CSV 文件包含您的扩展公钥(xpub),任何人都可以用它来:

  • 查看您的所有地址
  • 跟踪您的支付历史
  • 派生未来地址(仅 EVM/Tron)

不要

  • 公开分享 CSV 文件
  • 上传到不受信任的系统
  • 提交到版本控制

安全存储 CSV 文件,仅上传到受信任的 PayIn 实例。

步骤 5:验证地址(可选)

验证地址是否属于您的钱包:

bash
npm start
? Select an action: Verify Address Ownership
? Select protocol: EVM
? Do you have an existing mnemonic? Yes, use existing

? Enter your mnemonic phrase: [输入您的 12/24 个单词]

? Enter address to verify: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0
? Search range (max derivation index): 1000

Searching for address...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%

✅ ADDRESS FOUND!

Address: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0
Derivation Index: 0
Derivation Path: m/44'/60'/0'/0/0

验证用例

  • 确认地址属于您的钱包
  • 查找已知地址的派生索引
  • 审计导入的地址
  • 恢复地址信息

将地址导入 PayIn

生成地址后,通过 Admin UI 或 API 将其导入 PayIn 的地址池。

通过 Admin UI 导入(推荐)

Admin UI 提供用户友好的界面,可进行验证导入。

分步指南

  1. 登录 PayIn Admin

  2. 导航到地址池

    • 点击侧边栏中的**"Address Pool"**
    • 您将看到当前池统计信息
  3. 开始导入

    • 点击**"Import Addresses"**按钮
    • 导入对话框打开
  4. 选择导入模式

    ○ HD Wallet Import (Recommended)
    ○ Self-Managed Import
    • 如果您的 CSV 包含 derivation_indexmaster_public_key,选择 HD Wallet Import
    • 对于来自外部钱包的地址,选择 Self-Managed Import
  5. 上传 CSV 文件

    • 点击**"Choose File"**或拖放
    • 选择您导出的 CSV 文件
    • 等待文件验证
  6. 审查并确认

    Import Summary:
    - Protocol: EVM
    - Total Addresses: 1000
    - Derivation Range: 0 - 999
    - Master Public Key: xpub6CUG...
    
    ✓ All addresses are valid
    ✓ No duplicates found
    ✓ Format validation passed
  7. 开始导入

    • 点击**"Import"**
    • 进度条显示导入状态
    • 完成后接收确认

重复处理

PayIn 在导入期间自动跳过重复地址。如果地址已存在于池中,则不会再次导入。

通过 API 导入

对于自动化或编程导入,使用地址池 API。

端点POST /api/v1/address-pool/import

认证:需要具有 adminowner 角色的 API 密钥

请求

typescript
import fs from 'fs';

const csvContent = fs.readFileSync('evm-addresses-2025-01-20-full.csv', 'utf8');

const response = await fetch('https://testnet.payin.com/api/v1/address-pool/import', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.PAYIN_API_KEY}`
  },
  body: JSON.stringify({
    protocol: 'evm',
    mode: 'hd_wallet', // or 'self_managed'
    addresses: csvContent
  })
});

const result = await response.json();
console.log('Import result:', result);

响应

json
{
  "success": true,
  "imported": 1000,
  "skipped": 0,
  "errors": [],
  "summary": {
    "protocol": "evm",
    "mode": "hd_wallet",
    "derivation_range": {
      "start": 0,
      "end": 999
    },
    "master_public_key": "xpub6CUGRUonZSQ4TWUJKy..."
  }
}

错误响应(400 Bad Request):

json
{
  "success": false,
  "error": "Validation failed",
  "details": [
    {
      "line": 42,
      "address": "0xinvalid",
      "error": "Invalid EVM address format"
    }
  ]
}

Python 示例

python
import requests

with open('evm-addresses-2025-01-20-full.csv', 'r') as f:
    csv_content = f.read()

response = requests.post(
    'https://testnet.payin.com/api/v1/address-pool/import',
    headers={
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {os.getenv("PAYIN_API_KEY")}'
    },
    json={
        'protocol': 'evm',
        'mode': 'hd_wallet',
        'addresses': csv_content
    }
)

result = response.json()
print(f"Imported: {result['imported']} addresses")

批量导入策略

对于大型地址池(10,000+ 地址),使用批量导入:

策略

  1. 分批生成:创建每个包含 1000-5000 个地址的 CSV 文件
  2. 顺序导入:按顺序导入批次以避免超时
  3. 每批后验证:每批后检查池统计信息
  4. 跟踪进度:维护已导入批次的日志

批量工作流示例

bash
# 批次 1:地址 0-999
npm start
# 生成:start=0, count=1000
# 导出:evm-batch-1.csv

# 批次 2:地址 1000-1999
npm start
# 生成:start=1000, count=1000
# 导出:evm-batch-2.csv

# 批次 3:地址 2000-2999
npm start
# 生成:start=2000, count=1000
# 导出:evm-batch-3.csv

# 通过 Admin UI 导入每个批次

地址生命周期管理

了解地址如何在不同状态之间移动,有助于您有效管理池。

订单支付生命周期

场景:用户创建订单支付 100 USDT

步骤 1:订单创建
─────────────────────────────────────────────────────────────
POST /api/v1/orders
{
  "orderReference": "ORDER-2025-001",
  "amount": "100",
  "currency": "USDT",
  "chainId": "ethereum-sepolia"
}

↓ PayIn 从池中分配地址

Response:
{
  "orderId": "ord_abc123",
  "paymentAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0",
  "status": "pending"
}

地址状态:available → allocated
步骤 2:用户支付
─────────────────────────────────────────────────────────────
用户发送 100 USDT 到 0x742d35...

↓ PayIn 监控检测到交易
↓ 等待确认(默认:3 个区块)
↓ 订单完成

Webhook 事件:order.completed

地址状态:allocated(仍然保留)
步骤 3:地址释放
─────────────────────────────────────────────────────────────
订单完成后,PayIn 自动:
1. 从订单释放地址
2. 设置冷却期(30 分钟)
3. 地址进入冷却状态

地址状态:allocated → cooldown
步骤 4:返回池中
─────────────────────────────────────────────────────────────
冷却期过期后(30 分钟):
- 地址再次变为可用
- 可以分配给新订单
- 按 LRU(最近最少使用)优先

地址状态:cooldown → available

时间线

订单创建 ────→ 支付发送 ────→ 订单完成 ────→ 冷却过期
     ↓                    ↓                    ↓                     ↓
  allocated          allocated             cooldown              available
     0s               ~3 分钟              ~3 分 30 秒           ~33 分 30 秒

充值地址生命周期

场景:用户想要永久充值地址

步骤 1:地址绑定
─────────────────────────────────────────────────────────────
POST /api/v1/deposits/references
{
  "depositReference": "user_alice_123",
  "currency": "USDT",
  "chainId": "polygon-amoy"
}

↓ PayIn 分配并绑定地址

Response:
{
  "depositReference": "user_alice_123",
  "address": "0x9FF4e4b8a0451F7c8F7a1D8c1C6b5C2d3E4f5A6B",
  "protocol": "evm"
}

地址状态:available → bound
步骤 2:多次充值
─────────────────────────────────────────────────────────────
用户可以多次向同一地址充值:

充值 1:50 USDT  → 创建充值记录
充值 2:100 USDT → 创建另一个充值记录
充值 3:25 USDT  → 创建另一个充值记录

每次充值:
- 触发 webhook:deposit.pending → deposit.confirmed
- 记录金额和交易
- 地址保持绑定

地址状态:bound(永久)
步骤 3:地址解绑(可选)
─────────────────────────────────────────────────────────────
如果用户关闭账户或停止使用服务:

DELETE /api/v1/deposits/references/user_alice_123

↓ PayIn 解绑地址
↓ 设置冷却期(30 分钟)

地址状态:bound → cooldown → available

时间线

绑定 ────→ 充值 1 ────→ 充值 2 ────→ ... ────→ 解绑 ────→ 冷却 ────→ 可用
   ↓             ↓                ↓                           ↓            ↓              ↓
 bound         bound            bound                     cooldown      cooldown      available
   0s           小时             天                         ~0s         ~30 分钟       ~30 分钟

LRU 分配策略

PayIn 使用**最近最少使用(LRU)**算法高效分配地址。

分配优先级

sql
-- 1. 新地址(从未使用)
WHERE recycled_at IS NULL
ORDER BY created_at ASC

-- 2. 回收地址(之前使用过,已冷却)
WHERE recycled_at IS NOT NULL
  AND cooldown_until <= NOW()
ORDER BY recycled_at ASC

为什么使用 LRU?

  1. 公平性:所有地址随时间获得平等使用
  2. 隐私:最大化重用之间的时间
  3. 分布:防止热门地址
  4. 监控:确保旧监控任务清理

分配序列示例

池状态:
- 地址 A:recycled_at = NULL(新)
- 地址 B:recycled_at = 2025-01-20 10:00(2 小时前使用)
- 地址 C:recycled_at = 2025-01-20 11:30(30 分钟前使用)
- 地址 D:recycled_at = NULL(新)

分配顺序:
1. 地址 A(新地址,最先创建)
2. 地址 D(新地址,第二个创建)
3. 地址 B(回收,最旧)
4. 地址 C(回收,最新)

地址池监控

监控您的地址池健康状况,确保顺畅的支付操作。

池状态 API

获取实时池统计信息:

端点GET /api/v1/address-pool/status

请求

typescript
const response = await fetch('https://testnet.payin.com/api/v1/address-pool/status', {
  headers: {
    'Authorization': `Bearer ${process.env.PAYIN_API_KEY}`
  }
});

const status = await response.json();
console.log('Pool Status:', status);

响应

json
{
  "evm": {
    "total": 5000,
    "available": 4200,
    "allocated": 500,
    "bound": 250,
    "coolingDown": 50
  },
  "tron": {
    "total": 2000,
    "available": 1800,
    "allocated": 150,
    "bound": 40,
    "coolingDown": 10
  },
  "solana": {
    "total": 1000,
    "available": 950,
    "allocated": 30,
    "bound": 15,
    "coolingDown": 5
  }
}

Admin UI 仪表板

Admin UI 提供可视化池监控:

  1. 导航到地址池

    • 查看实时统计信息
    • 查看地址分配图表
  2. 池健康指标

    EVM 地址池                              ● 健康
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    总计:        5,000 地址
    可用:        4,200 (84%)  ▓▓▓▓▓▓▓▓░░
    已分配:        500 (10%)  ▓▓░░░░░░░░
    已绑定:        250 ( 5%)  ▓░░░░░░░░░
    冷却中:         50 ( 1%)  ░░░░░░░░░░
  3. 库存不足警告

    ⚠️ 警告:地址库存不足
    
    EVM 池仅有 120 个可用地址(2.4%)
    
    建议操作:
    1. 立即生成更多地址
    2. 将新批次导入池中
    3. 检查地址分配率

监控指标

要跟踪的关键指标

指标描述健康范围操作阈值
可用 %可用地址的百分比> 50%< 20%
分配率每小时分配的地址数不定急剧上升趋势
冷却 %冷却中的百分比< 5%> 10%
绑定增长充值绑定率不定意外峰值

库存不足警报

配置警报,在池库存不足时通知您。

Admin UI 配置

  1. 导航到设置 → 地址池

  2. 设置警报阈值

    库存不足警报:
    ┌─────────────────────────────────┐
    │ EVM:    [200] 地址              │
    │ Tron:   [100] 地址              │
    │ Solana: [50]  地址              │
    └─────────────────────────────────┘
    
    通知方式:
    ☑ 邮件
    ☑ Webhook
    ☐ 短信
  3. 测试警报

    • 点击 "Send Test Alert"
    • 验证您收到通知

邮件警报示例

主题:[PayIn 警报] 地址池库存不足

亲爱的 PayIn 用户,

您的 EVM 地址池库存不足:

当前状态:
- 可用:180 地址(3.6%)
- 总池:5,000 地址
- 阈值:200 地址(4%)

建议操作:
1. 使用 PayIn 地址工具生成 1,000+ 个新地址
2. 通过 Admin UI 导入地址
3. 检查分配模式

查看详情:https://testnet.payin.com/address-pool


PayIn 警报系统

Webhook 警报负载

json
{
  "type": "alert.address_pool_low",
  "timestamp": "2025-01-20T15:30:00Z",
  "data": {
    "protocol": "evm",
    "available": 180,
    "total": 5000,
    "percentage": 3.6,
    "threshold": 200
  }
}

主动池管理

最佳实践

  1. 每日监控:至少每天检查一次池状态
  2. 维持缓冲:保持 50%+ 可用地址
  3. 批量生成:每批生成 1000+ 地址
  4. 预测性扩展:监控分配趋势,主动添加地址
  5. 协议平衡:确保每个协议都有足够的地址

监控脚本示例

typescript
// check-pool-health.ts
import { PayInClient } from '@payin/sdk';

const client = new PayInClient({
  apiKey: process.env.PAYIN_API_KEY,
  baseUrl: 'https://testnet.payin.com'
});

async function checkPoolHealth() {
  const status = await client.addressPool.getStatus();

  for (const [protocol, stats] of Object.entries(status)) {
    const availablePercent = (stats.available / stats.total) * 100;

    if (availablePercent < 20) {
      console.error(`❌ 严重:${protocol} 池在 ${availablePercent.toFixed(1)}%`);
      // 发送警报
    } else if (availablePercent < 50) {
      console.warn(`⚠️  警告:${protocol} 池在 ${availablePercent.toFixed(1)}%`);
      // 考虑生成更多
    } else {
      console.log(`✅ 正常:${protocol} 池在 ${availablePercent.toFixed(1)}%`);
    }
  }
}

// 每小时运行一次
setInterval(checkPoolHealth, 60 * 60 * 1000);
checkPoolHealth();

Cron 作业设置

bash
# 添加到 crontab(每 4 小时运行一次)
0 */4 * * * cd /path/to/scripts && node check-pool-health.js

自管理地址导入

对于希望在 HD 钱包系统之外管理自己的密钥和地址的用户。

准备自管理地址

步骤 1:生成地址

使用您喜欢的钱包软件:

bash
# 使用 ethers.js(EVM)
import { Wallet } from 'ethers';

const addresses = [];
for (let i = 0; i < 1000; i++) {
  const wallet = Wallet.createRandom();
  addresses.push({
    address: wallet.address,
    privateKey: wallet.privateKey // 安全存储,不要包含在 CSV 中!
  });
}

# 安全保存私钥(加密文件、硬件钱包等)
# 仅将地址导出到 CSV
bash
# 使用 TronWeb(Tron)
import TronWeb from 'tronweb';

const addresses = [];
for (let i = 0; i < 1000; i++) {
  const account = await TronWeb.createAccount();
  addresses.push({
    address: account.address.base58,
    privateKey: account.privateKey // 安全存储!
  });
}

步骤 2:创建 CSV 文件

自管理地址的格式:

csv
address,protocol,derivation_index,master_public_key
0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0,evm,,
0x5AEDA56215b167893e80B4fE645BA6d5Bab767DE,evm,,
0x9FF4e4b8a0451F7c8F7a1D8c1C6b5C2d3E4f5A6B,evm,,
TYASr5UV6HEcXatwdFQfmLVUqQQQMUxHLS,tron,,
TPJRnELdwXLWVvokPJyT3CHPF4YPKVkrSU,tron,,

关键点

  • derivation_indexmaster_public_key 留空
  • 仅包含公共地址(永远不要包含私钥!)
  • 每行一个地址
  • 协议必须是 evmtronsolana

步骤 3:验证地址

导入前,在本地验证地址:

typescript
// validate-addresses.ts
import { isAddress } from 'ethers';
import fs from 'fs';
import csv from 'csv-parse/sync';

const content = fs.readFileSync('self-managed-addresses.csv', 'utf8');
const records = csv.parse(content, { columns: true });

let errors = 0;
for (const [index, record] of records.entries()) {
  if (record.protocol === 'evm' && !isAddress(record.address)) {
    console.error(`行 ${index + 2}:无效的 EVM 地址:${record.address}`);
    errors++;
  }
  // 为 Tron 和 Solana 地址添加验证
}

if (errors === 0) {
  console.log('✅ 所有地址均有效');
} else {
  console.error(`❌ 发现 ${errors} 个无效地址`);
  process.exit(1);
}

导入流程

通过 Admin UI

  1. 导航到地址池 → 导入地址
  2. 选择**"Self-Managed Import"**
  3. 上传 CSV 文件
  4. 审查导入摘要
  5. 确认导入

通过 API

typescript
const csvContent = fs.readFileSync('self-managed-addresses.csv', 'utf8');

const response = await fetch('https://testnet.payin.com/api/v1/address-pool/import', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.PAYIN_API_KEY}`
  },
  body: JSON.stringify({
    protocol: 'evm',
    mode: 'self_managed',
    addresses: csvContent
  })
});

const result = await response.json();
console.log(`导入了 ${result.imported} 个自管理地址`);

安全注意事项

自管理模式责任

  1. 私钥管理

    • 安全存储私钥(硬件钱包、加密存储)
    • 永远不要在 CSV 导入中包含私钥
    • 实施密钥轮换策略
    • 在多个安全位置备份密钥
  2. 地址跟踪

    • 维护您自己的地址到密钥的映射
    • 记录地址生成方法
    • 跟踪哪些地址已导入 PayIn
  3. 恢复规划

    • 记录密钥恢复程序
    • 定期测试恢复流程
    • 确保继任者在需要时可以访问密钥

关键:私钥安全

PayIn 永远不会要求或存储您的私钥。如果有人声称来自 PayIn 并要求您的私钥,那是诈骗。仅将公共地址导入 PayIn。

最佳实践

HD 钱包模式

安全最佳实践

  1. 助记词存储

    • ✅ 写在纸上,存放在保险箱/金库中
    • ✅ 在不同位置创建多个备份
    • ✅ 使用金属备份板以防火/水
    • ✅ 企业考虑 Shamir 秘密共享
    • ❌ 永远不要数字存储(计算机、手机、云)
    • ❌ 永远不要拍照
    • ❌ 永远不要与任何人分享
  2. 生成环境

    • ✅ 使用离线/气隙计算机生成
    • ✅ 验证工具完整性(校验和、签名)
    • ✅ 生成期间断开网络
    • ❌ 不要在共享/公共计算机上生成
  3. 验证

    • ✅ 导入后验证前几个地址
    • ✅ 在生产使用前测试小额支付
    • ✅ 记录使用的派生路径

操作最佳实践

  1. 批量管理

    • 分批生成地址(1000-5000)
    • 跟踪派生范围(0-999、1000-1999 等)
    • 用日期记录批量导入
    • 维护批量生成日志
  2. 池大小

    • 维持 50%+ 可用地址
    • 主动生成新批次
    • 监控分配率趋势
    • 在不足之前扩展
  3. 可追溯性

    • 保留所有导入记录(批次文件、日期)
    • 记录主公钥
    • 跟踪派生索引范围
    • 定期审计池

自管理模式

密钥管理

  1. 私钥安全

    • 尽可能使用硬件钱包
    • 加密私钥存储
    • 实施访问控制
    • 定期安全审计
  2. 地址生成

    • 使用信誉良好的钱包软件
    • 导入前验证地址格式
    • 检查重复
    • 记录生成方法
  3. 备份策略

    • 多个安全备份
    • 地理分布
    • 定期备份验证
    • 记录恢复程序

导入最佳实践

  1. 验证

    • 导入前验证所有地址
    • 检查格式错误
    • 验证无重复
    • 先测试小批次
  2. 文档

    • 维护地址到密钥的映射
    • 记录导入日期和批次
    • 跟踪哪些地址在 PayIn 中
    • 记录任何地址轮换

一般最佳实践

池管理

  1. 监控

    • 每天检查池状态
    • 设置库存不足警报
    • 监控分配模式
    • 跟踪冷却率
  2. 维护

    • 定期池审计
    • 检查地址状态
    • 清理过时绑定
    • 根据需要更新冷却配置
  3. 扩展

    • 监控业务增长
    • 主动扩展
    • 为高峰期做计划
    • 维持足够缓冲

安全

  1. 访问控制

    • 限制谁可以导入地址
    • 使用具有适当权限的 API 密钥
    • 审计导入活动
    • 监控未授权访问尝试
  2. 地址隐私

    • 不要不必要地重用地址
    • 尊重冷却期
    • 考虑解绑未使用的充值地址
    • 定期轮换地址池

操作

  1. 测试

    • 先在测试网上测试地址分配
    • 验证导入流程正确工作
    • 测试池耗尽场景
    • 练习紧急程序
  2. 文档

    • 记录您的地址管理流程
    • 保留导入日志
    • 维护常见任务的运行手册
    • 培训团队成员

安全注意事项

助记词安全

关键:您的助记词是从中生成的所有地址的主密钥。

威胁模型

威胁影响缓解措施
物理盗窃攻击者获得完全访问权限多个安全位置、分割存储
数字暴露恶意软件/黑客访问永远不要数字存储、离线生成
社会工程被骗透露教育、验证程序
丢失/销毁永久失去访问权限多个备份、金属板

纵深防御

第 1 层:离线生成
- 在气隙计算机上生成
- 使用经过验证的开源工具
- 生成期间断开网络

第 2 层:物理安全
- 存放在保险箱/金库中
- 多个地理位置
- 防火/防水容器

第 3 层:访问控制
- 限制知道助记词存储位置的人
- 多人访问要求(企业)
- 定期安全审查

第 4 层:备份策略
- 多个副本
- 不同格式(纸、金属)
- 不同位置
- 定期验证

地址验证

导入验证

PayIn 在地址导入期间执行全面验证:

  1. 格式验证

    • EVM:校验和地址格式(0x + 40 个十六进制字符)
    • Tron:以 'T' 开头的 Base58 格式
    • Solana:Base58 格式(32-44 个字符)
  2. 重复检测

    • 检查现有池地址
    • 防止重复导入
    • 在 CSV 文件内验证
  3. 协议一致性

    • 确保地址与指定协议匹配
    • 检测格式不匹配
    • 验证派生数据一致性

黑名单检查

未来功能

PayIn 计划添加对已知恶意地址的地址黑名单检查支持。这将有助于防止导入受损地址。

目前,实施您自己的黑名单检查:

typescript
// check-blacklist.ts
import fs from 'fs';
import csv from 'csv-parse/sync';

// 从公共来源加载黑名单
const blacklist = new Set([
  '0x...',  // 已知诈骗地址
  // 添加更多
]);

const addresses = csv.parse(
  fs.readFileSync('addresses.csv', 'utf8'),
  { columns: true }
);

for (const record of addresses) {
  if (blacklist.has(record.address.toLowerCase())) {
    console.error(`❌ 发现黑名单地址:${record.address}`);
    process.exit(1);
  }
}

console.log('✅ 未发现黑名单地址');

导入验证

导入地址后,验证导入是否成功:

验证步骤

  1. 检查池统计信息

    typescript
    const status = await client.addressPool.getStatus();
    console.log(`总 EVM 地址:${status.evm.total}`);
    // 应该匹配预期计数
  2. 抽查地址

    typescript
    // 验证导入中的随机地址存在于池中
    const response = await client.addressPool.listAddresses({
      protocol: 'evm',
      page: 1,
      pageSize: 10
    });
    
    // 检查 CSV 中的地址是否出现
  3. 测试分配

    typescript
    // 创建测试订单以验证分配有效
    const order = await client.orders.create({
      orderReference: 'TEST-VERIFICATION',
      amount: '1',
      currency: 'USDT',
      chainId: 'ethereum-sepolia'
    });
    
    // 验证分配的地址来自您导入的集合
    console.log(`分配的地址:${order.paymentAddress}`);

审计日志

PayIn 为地址池操作维护全面的审计日志:

记录的事件

  • 地址导入(谁、何时、多少)
  • 地址分配(订单/充值)
  • 地址释放
  • 地址绑定/解绑
  • 池配置更改

访问审计日志

typescript
const logs = await client.addressPool.getAuditLogs({
  startDate: '2025-01-20',
  endDate: '2025-01-21',
  eventType: 'import'
});

for (const log of logs.entries) {
  console.log(`${log.timestamp}:${log.eventType} 由 ${log.user} - ${log.count} 地址`);
}

故障排除

常见问题

1. 导入失败:"Invalid address format"

原因:地址与协议的预期格式不匹配。

解决方案

bash
# 验证 EVM 地址
import { isAddress } from 'ethers';
console.log(isAddress('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0')); // true

# 确保地址是校验和格式
import { getAddress } from 'ethers';
const checksummed = getAddress('0x742d35cc6634c0532925a3b844bc9e7595f0beb0');
console.log(checksummed); // 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0

2. 导入失败:"Duplicate addresses found"

原因:地址已存在于池中或在 CSV 中多次出现。

解决方案

typescript
// 检查 CSV 中的重复
const addresses = records.map(r => r.address.toLowerCase());
const unique = new Set(addresses);
if (addresses.length !== unique.size) {
  console.error('CSV 包含重复地址');
}

// 检查现有池
const existing = await client.addressPool.checkAddresses(addresses);
console.log(`${existing.duplicates.length} 地址已在池中`);

3. "No available addresses in pool"

原因:所有地址都已分配、绑定或处于冷却中。

解决方案

  1. 检查池状态

    typescript
    const status = await client.addressPool.getStatus();
    console.log(status);
  2. 生成并导入更多地址(立即修复)

  3. 检查分配模式(长期修复):

    • 订单是否正确过期?
    • 地址是否正在释放?
    • 冷却期是否太长?
    • 分配率是否高于预期?

4. 地址工具:"Invalid mnemonic phrase"

原因:助记词有拼写错误、单词数量错误或无效单词。

解决方案

bash
# 验证助记词单词数(12 或 24)
echo "your mnemonic words here" | wc -w

# 检查单词拼写错误(使用 BIP39 单词列表)

# 常见错误:
# - 单词之间有多余空格
# - 单词顺序错误
# - 单词不在 BIP39 列表中

5. 验证:"Address not found in wallet"

原因:地址不属于助记词,或搜索范围太小。

解决方案

bash
# 增加搜索范围
? Search range: 5000  # 而不是默认的 1000

# 验证您使用的是正确的:
# - 助记词
# - 协议(EVM vs Tron vs Solana)
# - 派生路径

6. 池性能低下

原因:冷却中地址过多,频繁的分配/释放周期。

解决方案

  1. 增加池大小:更多地址 = 更好的性能
  2. 调整冷却期:如果您的用例不需要,可以减少
    typescript
    await client.config.update({
      'address_pool.cooldown_minutes': 15  // 从 30 减少到 15
    });
  3. 检查分配策略:您是否创建了太多短期订单?

获取帮助

如果您遇到此处未涵盖的问题:

  1. 检查 API 日志

    • 审查错误响应
    • 检查 HTTP 状态码
    • 查找详细错误消息
  2. Admin UI 诊断

    • 导航到地址池
    • 检查 "Pool Health" 选项卡
    • 审查最近的活动日志
  3. 联系支持

    • 邮箱:support@payin.com
    • 包括:池统计信息、错误消息、CSV 样本
    • 指定:协议、导入模式、环境(测试网/主网)
  4. 社区

后续步骤

现在您了解了地址管理,探索这些相关主题:

必读内容

API 参考

高级主题

工具

总结

关键要点

地址池实现即时支付地址分配和高效重用

HD 钱包模式(推荐)使用 BIP44 标准,提供完整工具支持

自管理模式为高级用户提供灵活性

LRU 分配确保公平分布和隐私保护

冷却期(30 分钟)保护隐私并允许结算

监控至关重要 - 维持 50%+ 可用地址

安全需要正确的助记词存储和验证

快速参考

任务工具/方法所需时间
生成 1000 个地址PayIn 地址工具~2 分钟
导入地址Admin UI 或 API~1 分钟
检查池状态Admin UI 或 API即时
分配地址自动(API 调用)< 100ms
释放地址自动(订单完成)< 100ms

生产检查清单

  • [ ] 助记词已生成并安全存储(多个备份)
  • [ ] 为所有需要的协议生成地址(EVM、Tron、Solana)
  • [ ] 地址已导入 PayIn(通过池状态验证)
  • [ ] 已配置库存不足警报
  • [ ] 已设置池监控(每日检查或自动化)
  • [ ] 团队已培训地址生成流程
  • [ ] 已记录紧急程序
  • [ ] 已建立备份生成能力

您现在已准备好为 PayIn 支付基础设施高效管理地址!

Released under the MIT License.