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 后,你应该能够: