Day 2

账户管理与密钥

初级阶段 · 预计学习时间 2-3 小时

学习目标
  • 生成新的密钥对
  • 安全保存私钥到 Keystore
  • 从 Keystore 加载账户
  • 使用账户签名消息
账户概念

Aeternity 账户由一对密钥组成:

类型格式用途
公钥(地址) ak_... 接收转账、标识身份
私钥 64字符十六进制 签名交易、控制账户
安全警告: 私钥绝对不能分享或提交到代码仓库!
创建新账户
package main

import (
    "fmt"
    "log"

    "github.com/aeternity/aepp-sdk-go/v9/account"
)

func main() {
    // 生成新账户
    acc, err := account.New()
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("=== 新账户已创建 ===")
    fmt.Printf("地址 (公钥): %s\n", acc.Address)
    fmt.Printf("私钥 (Hex):  %s\n", acc.SigningKeyToHexString())
}
注意: 上述代码仅用于演示。实际应用中不要直接打印私钥。
Keystore 存储

Keystore 使用 Web3 Secret Storage 格式,私钥经过密码加密存储。

保存到 Keystore
// 创建账户后...
password := "my_secure_password"
filename := "my_wallet.json"

// 加密并保存到文件
path, err := account.StoreToKeyStoreFile(acc, password, filename)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("钱包已保存到: %s\n", path)
从 Keystore 加载
// 使用密码加载钱包
loadedAcc, err := account.LoadFromKeyStoreFile("my_wallet.json", "my_secure_password")
if err != nil {
    log.Fatal("加载钱包失败:", err)
}

fmt.Printf("加载的地址: %s\n", loadedAcc.Address)
消息签名

账户可以签名任意消息,用于身份验证或离线授权。

// 待签名的消息
msg := []byte("Hello Aeternity")

// 使用私钥签名
signature := acc.Sign(msg)

fmt.Printf("消息: %s\n", string(msg))
fmt.Printf("签名: %x\n", signature)
fmt.Printf("签名长度: %d 字节\n", len(signature))
签名验证(概念)

签名可以被任何持有公钥的人验证,证明消息确实来自该账户持有者。

完整示例
package main

import (
    "fmt"
    "log"
    "os"

    "github.com/aeternity/aepp-sdk-go/v9/account"
)

func main() {
    walletFile := "demo_wallet.json"
    password := "demo_password"

    var acc *account.Account
    var err error

    // 检查钱包是否存在
    if _, err := os.Stat(walletFile); os.IsNotExist(err) {
        // 创建新钱包
        fmt.Println("创建新钱包...")
        acc, err = account.New()
        if err != nil {
            log.Fatal(err)
        }
        
        // 保存到文件
        _, err = account.StoreToKeyStoreFile(acc, password, walletFile)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println("✅ 钱包已创建并保存")
    } else {
        // 加载现有钱包
        fmt.Println("加载现有钱包...")
        acc, err = account.LoadFromKeyStoreFile(walletFile, password)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println("✅ 钱包已加载")
    }

    fmt.Printf("\n地址: %s\n", acc.Address)
    
    // 签名测试
    testMsg := []byte("Test message")
    sig := acc.Sign(testMsg)
    fmt.Printf("签名测试: %x...\n", sig[:16])
}
知识检查点

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