Day 2 账户体系与密钥管理

掌握账户创建、密钥存储和助记词钱包的使用。

学习目标
  • 理解 Aeternity 账户地址的编码规则
  • 掌握私钥、公钥与地址的关系
  • 熟练使用 Account 类进行账户管理
  • 掌握助记词钱包的使用方法

1. 账户地址编码

1.1 地址格式
前缀类型编码示例
ak_账户地址Base58ak_2swhLkgB...
ct_合约地址Base58ct_2AfnEfC...
ok_预言机地址Base58ok_2swhLkgB...
nm_域名 IDBase58nm_2sFnPH...
th_交易哈希Base58th_2AfnEfC...
kh_关键块哈希Base58kh_2sFnPH...
cb_字节码Base64cb_+QEWA...
1.2 地址生成流程
┌─────────────────────────────────────────────────────────────┐
│                    地址生成流程                              │
├─────────────────────────────────────────────────────────────┤
│   随机数 (32 字节)                                          │
│        │                                                    │
│        ▼                                                    │
│   ED25519 私钥 (64 字节)                                    │
│        │                                                    │
│        ▼                                                    │
│   ED25519 公钥 (32 字节)                                    │
│        │                                                    │
│        ▼                                                    │
│   Base58Check 编码                                          │
│        │                                                    │
│        ▼                                                    │
│   添加 "ak_" 前缀 → ak_2swhLkgBPeeADxV...                  │
└─────────────────────────────────────────────────────────────┘

2. Keystore 加密机制

2.1 加密标准
组件算法说明
密钥派生Argon2id抗 GPU 攻击的密码哈希
对称加密XSalsa20-Poly1305NaCl SecretBox
认证Poly1305 MAC消息认证码

3. BIP39/BIP44 标准

助记词是一组易于记忆的单词,用于备份和恢复钱包:

  • 支持 12/15/18/21/24 个单词
  • 从 2048 个英文单词中选取
  • 包含校验和
BIP44 派生路径
m / purpose' / coin_type' / account' / change' / address_index'
m / 44'      / 457'       / 0'       / 0'      / 0'

参数说明:
- purpose': 固定为 44(BIP44 标准)
- coin_type': 457(Aeternity 的注册号)
- account': 账户索引(0, 1, 2...)
- change': 固定为 0
- address_index': 地址索引(0, 1, 2...)

4. 实践任务

任务 2.1: 生成和管理账户
from aeternity.signing import Account
from aeternity.identifiers import ACCOUNT_API_FORMAT, ACCOUNT_SOFIA_FORMAT

# 生成新账户
account = Account.generate()

# 获取地址(不同格式)
api_address = account.get_address()
sophia_address = account.get_address(ACCOUNT_SOFIA_FORMAT)

print(f"=== 新账户信息 ===")
print(f"API 地址: {api_address}")
print(f"Sophia 地址: {sophia_address}")

# 获取私钥(十六进制)
private_key = account.get_secret_key()
print(f"\n私钥: {private_key[:32]}...{private_key[-32:]}")
print(f"私钥长度: {len(private_key)} 字符 ({len(private_key)//2} 字节)")

# 从私钥恢复账户
recovered = Account.from_secret_key_string(private_key)
print(f"\n=== 恢复验证 ===")
print(f"恢复的地址: {recovered.get_address()}")
print(f"地址匹配: {recovered.get_address() == api_address}")
任务 2.2: 使用 Keystore
from aeternity.signing import Account
import os
import json

# 生成账户
account = Account.generate()
original_address = account.get_address()

print(f"=== 原始账户 ===")
print(f"地址: {original_address}")

# 保存到 Keystore 文件
keystore_path = "test_wallet.json"
password = "SecurePassword123!"

account.save_to_keystore_file(keystore_path, password)
print(f"\n✅ Keystore 已保存到: {keystore_path}")

# 查看 Keystore 内容
with open(keystore_path) as f:
    keystore = json.load(f)
    print(f"\nKeystore 结构:")
    print(f"  公钥: {keystore.get('public_key', 'N/A')[:30]}...")
    print(f"  加密算法: {keystore['crypto']['symmetric_alg']}")
    print(f"  密钥派生: {keystore['crypto']['kdf']}")

# 从 Keystore 加载
loaded_account = Account.from_keystore(keystore_path, password)
loaded_address = loaded_account.get_address()

print(f"\n=== 恢复验证 ===")
print(f"加载的地址: {loaded_address}")
print(f"地址匹配: {loaded_address == original_address}")

# 测试错误密码
try:
    Account.from_keystore(keystore_path, "wrong_password")
except ValueError as e:
    print(f"\n✅ 错误密码被正确拒绝")

# 清理测试文件
os.remove(keystore_path)
任务 2.3: 创建助记词钱包
from aeternity.wallet import MnemonicWallet

# 生成新钱包
wallet = MnemonicWallet.generate()

print(f"=== 新助记词钱包 ===")
print(f"助记词: {wallet.mnemonic}")
print(f"\n⚠️ 请安全保存助记词!任何拥有助记词的人都可以控制你的资产!")
print(f"\n主地址: {wallet.address}")

# 获取主账户
master_account = wallet.account
print(f"主账户私钥: {master_account.get_secret_key()[:32]}...")

# 从助记词恢复
print(f"\n=== 恢复测试 ===")
recovered_wallet = MnemonicWallet.from_mnemonic(wallet.mnemonic)
print(f"恢复后地址: {recovered_wallet.address}")
print(f"地址匹配: {recovered_wallet.address == wallet.address}")
任务 2.4: HD 钱包派生
from aeternity.hdwallet import HDWallet

# 创建 HD 钱包
wallet = HDWallet()

print(f"=== HD 钱包 ===")
print(f"助记词: {wallet.mnemonic}")
print(f"\n派生路径格式: m/44'/457'/account'/0'/address'")

# 获取主账户 (m/44'/457'/0'/0'/0')
master_account = wallet.get_master_account()
print(f"\n主账户:")
print(f"  路径: m/44'/457'/0'/0'/0'")
print(f"  地址: {master_account.get_address()}")

# 派生多个子账户
print(f"\n派生子账户:")
for i in range(5):
    path, account = wallet.derive_child(account_index=i, address_index=0)
    print(f"  {path}")
    print(f"    → {account.get_address()}")
任务 2.5: 消息签名和验证
from aeternity.signing import Account, is_signature_valid

# 生成账户
account = Account.generate()
address = account.get_address()

print(f"=== 消息签名 ===")
print(f"账户地址: {address}")

# 签名消息
message = b"Hello, Aeternity Blockchain!"
signature = account.sign(message)

print(f"\n原始消息: {message.decode()}")
print(f"签名: {signature.hex()[:64]}...")
print(f"签名长度: {len(signature)} 字节")

# 使用 Account.verify 验证
print(f"\n=== 验证签名 ===")
try:
    account.verify(message, signature)
    print("✅ 签名验证成功 (Account.verify)")
except Exception as e:
    print(f"❌ 签名验证失败: {e}")

# 使用独立函数验证
is_valid = is_signature_valid(address, signature, message)
print(f"✅ is_signature_valid 结果: {is_valid}")

# 验证错误的消息
print(f"\n=== 篡改检测 ===")
wrong_message = b"Tampered message"
is_valid = is_signature_valid(address, signature, wrong_message)
print(f"篡改消息验证结果: {is_valid} (预期: False)")
知识检查点

完成 Day 2 后,你应该能够:

  • 解释地址编码规则(ak_ 前缀、Base58)
  • 生成和恢复账户
  • 使用 Keystore 加密存储私钥
  • 创建和使用助记词钱包
  • 派生 HD 钱包子账户
  • 签名和验证消息
本页目录