# aeknow Python SDK

aeknow 区块链 Python SDK，提供完整的账户管理、交易构建、合约部署、AENS域名服务等功能。

## 目录

- [安装](#安装)
- [快速开始](#快速开始)
- [模块说明](#模块说明)
  - [signing - 账户与签名](#signing---账户与签名)
  - [wallet - 助记词钱包](#wallet---助记词钱包)
  - [hdwallet - HD钱包核心](#hdwallet---hd钱包核心)
  - [message - 消息签名](#message---消息签名)
  - [crypto - 消息加密](#crypto---消息加密)
  - [hashing - 哈希工具](#hashing---哈希工具)
  - [node - 节点客户端](#node---节点客户端)
  - [compiler - 编译器客户端](#compiler---编译器客户端)
  - [contract - 合约模块](#contract---合约模块)
  - [contract_native - 原生合约管理](#contract_native---原生合约管理)
  - [transactions - 交易构建](#transactions---交易构建)
  - [aens - 域名服务](#aens---域名服务)
  - [oracles - 预言机](#oracles---预言机)
  - [utils - 工具函数](#utils---工具函数)
  - [defaults - 默认配置](#defaults---默认配置)
  - [identifiers - 标识符常量](#identifiers---标识符常量)

---

## 安装

```bash
pip install aeknow
```

### 依赖项

核心依赖：

| 包名 | 版本要求 | 说明 |
|------|----------|------|
| `pynacl` | >=1.4.0 | NaCl 加密库，用于签名和加密 |
| `base58` | >=2.1.0 | Base58 编解码 |
| `mnemonic` | >=0.20 | BIP39 助记词生成与验证 |
| `requests` | >=2.28.0 | HTTP 网络请求 |
| `rlp` | >=3.0.0 | RLP 编解码 |

安装依赖：
```bash
pip install pynacl base58 mnemonic requests rlp
```

或一键安装所有依赖：
```bash
pip install aeknow[all]
```

---

## 快速开始

```python
from aeknow.signing import Account
from aeknow.node import NodeClient, Config

# 创建节点客户端
client = NodeClient(Config(external_url='https://sdk-mainnet.aepps.com'))

# 生成新账户
account = Account.generate()
print(f"地址: {account.get_address()}")
print(f"私钥: {account.get_secret_key()}")

# 查询余额
balance = client.get_balance(account.get_address())
print(f"余额: {balance} aettos")

# 转账
# tx = client.spend(account, "ak_recipient...", 1000000000000000000)
```

---

## 模块说明

---

## signing - 账户与签名

账户管理核心模块，提供密钥生成、签名、Keystore 加解密等功能。

### Account 类

#### 生成新账户

```python
from aeknow.signing import Account

# 生成随机账户
account = Account.generate()
print(account.get_address())  # ak_2swhL...
```

#### 从私钥导入

```python
# 从 64 字节十六进制私钥导入
account = Account.from_secret_key_string("your_hex_secret_key_here")
print(account.get_address())
```

#### 从 Keystore 加载

```python
# 加载 Keystore 文件
account = Account.from_keystore("path/to/keystore.json", "password")
print(account.get_address())
```

#### 保存到 Keystore

```python
account = Account.generate()

# 保存到指定文件
account.save_to_keystore_file("wallet.json", "password")

# 保存到目录（自动生成文件名）
account.save_to_keystore("./keystores/", "password")
```

#### 获取地址（不同格式）

```python
from aeknow.identifiers import ACCOUNT_API_FORMAT, ACCOUNT_SOFIA_FORMAT, ACCOUNT_RAW_FORMAT

# API 格式 (默认)
address = account.get_address()  # ak_2swhL...

# Sophia 格式 (合约使用)
address_sophia = account.get_address(ACCOUNT_SOFIA_FORMAT)  # 0x...

# 原始字节
address_raw = account.get_address(ACCOUNT_RAW_FORMAT)  # bytes
```

#### 签名数据

```python
data = b"Hello aeknow"
signature = account.sign(data)
print(signature.hex())
```

#### 验证签名

```python
try:
    account.verify(data, signature)
    print("签名有效")
except:
    print("签名无效")
```

### 独立函数

#### is_signature_valid - 验证签名

```python
from aeknow.signing import is_signature_valid

is_valid = is_signature_valid(
    account_id="ak_2swhL...",
    signature=signature_bytes,
    data=b"Hello aeknow"
)
print(f"签名有效: {is_valid}")
```

#### keystore_seal - 创建 Keystore

```python
from aeknow.signing import keystore_seal

keystore = keystore_seal(
    secret_key=account.signing_key,
    password="your_password",
    name="my_wallet"
)
```

#### keystore_open - 解密 Keystore

```python
from aeknow.signing import keystore_open
import json

with open("wallet.json") as f:
    keystore = json.load(f)
    
private_key = keystore_open(keystore, "password")
```

---

## wallet - 助记词钱包

对 HDWallet 的高级封装，提供简洁的助记词钱包操作接口。

### MnemonicWallet 类

#### 生成新钱包

```python
from aeknow.wallet import MnemonicWallet

wallet = MnemonicWallet.generate()
print(f"助记词: {wallet.mnemonic}")
print(f"主地址: {wallet.address}")
```

#### 从助记词导入

```python
mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
wallet = MnemonicWallet.from_mnemonic(mnemonic)
print(wallet.address)
```

#### 从 Keystore 加载

```python
wallet = MnemonicWallet.from_keystore("mnemonic_wallet.json", "password")
print(wallet.mnemonic)
```

#### 获取主账户

```python
account = wallet.account  # Account 对象
print(account.get_address())
```

#### 派生子账户

```python
# 派生单个账户
child_account = wallet.derive_account(index=0)
print(child_account.get_address())

# 派生多个账户
accounts = wallet.derive_accounts(count=5)
for path, acc in accounts:
    print(f"{path}: {acc.get_address()}")
```

#### 保存钱包

```python
# 保存助记词 Keystore
wallet.save_keystore("mnemonic_wallet.json", "password")

# 保存单个账户 Keystore
wallet.save_account_keystore("account_0.json", "password", index=0)
```

### 便捷函数

```python
from aeknow.wallet import generate_wallet, import_wallet, load_wallet

# 生成新钱包
wallet = generate_wallet()

# 从助记词导入
wallet = import_wallet("your mnemonic words here")

# 从 Keystore 加载
wallet = load_wallet("wallet.json", "password")
```

---

## hdwallet - HD钱包核心

BIP39/BIP44 标准的 HD 钱包实现。

### HDWallet 类

#### 创建钱包

```python
from aeknow.hdwallet import HDWallet

# 生成新助记词
wallet = HDWallet()
print(wallet.mnemonic)

# 从已有助记词创建
wallet = HDWallet("your mnemonic words here")
```

#### 生成助记词

```python
mnemonic = HDWallet.generate_mnemonic()
print(mnemonic)  # 12 个单词
```

#### 获取主账户

```python
master = wallet.get_master_account()
print(master.get_address())  # m/44'/457'/0'/0'/0'
```

#### 派生子账户

```python
# 派生路径: m/44'/457'/{account_index}'/0'/{address_index}'
path, account = wallet.derive_child(account_index=0, address_index=0)
print(f"{path}: {account.get_address()}")

# 自动递增 account_index
path1, acc1 = wallet.derive_child()  # account_index=1
path2, acc2 = wallet.derive_child()  # account_index=2
```

#### 保存/加载助记词 Keystore

```python
# 保存
wallet.save_mnemonic_to_keystore_file("mnemonic.json", "password")

# 加载
wallet = HDWallet.from_keystore("mnemonic.json", "password")
```

---

## message - 消息签名

兼容 aepp-sdk-js 的消息签名模块。

### 核心函数

#### hash_message - 计算消息哈希

```python
from aeknow.message import hash_message

# 按 AE SDK 标准格式计算哈希
msg_hash = hash_message("Hello aeknow!")
print(msg_hash.hex())
```

#### sign_message - 签名消息

```python
from aeknow.message import sign_message
from aeknow.signing import Account

account = Account.generate()
signature = sign_message(account, "Hello aeknow!")
print(f"签名: {signature}")  # 128 字符十六进制
```

#### verify_message - 验证签名

```python
from aeknow.message import verify_message

is_valid = verify_message(
    address="ak_2swhL...",
    message="Hello aeknow!",
    signature="signature_hex_here"
)
print(f"签名有效: {is_valid}")
```

### MessageSigner 类

```python
from aeknow.message import MessageSigner

# 从 Keystore 加载
signer = MessageSigner.from_keystore("wallet.json", "password")

# 或从私钥加载
signer = MessageSigner.from_secret_key("hex_secret_key")

# 或生成新账户
signer = MessageSigner.generate()

# 签名
result = signer.sign("Hello!")
print(result)
# {
#     'message': 'Hello!',
#     'address': 'ak_...',
#     'signature': '...',
#     'message_hash': '...'
# }

# 验证
is_valid = signer.verify("ak_...", "Hello!", "signature_hex")
```

---

## crypto - 消息加密

基于 ED25519 -> X25519 密钥转换的 NaCl 加密模块。

### 加密方案

| 方案 | 说明 | 适用场景 |
|------|------|----------|
| SealedBox | 匿名加密，只需接收方公钥 | 公开投递、匿名消息 |
| Box | 双向认证加密，验证双方身份 | 私密通信、身份验证 |

### 核心函数

#### sealed_encrypt / sealed_decrypt - 匿名加密

```python
from aeknow.crypto import sealed_encrypt, sealed_decrypt
from aeknow.signing import Account

# 加密（只需接收方地址）
ciphertext = sealed_encrypt("秘密消息", "ak_recipient...")

# 解密（需要接收方账户）
recipient = Account.from_keystore("recipient.json", "password")
plaintext = sealed_decrypt(ciphertext, recipient)
```

#### box_encrypt / box_decrypt - 双向认证加密

```python
from aeknow.crypto import box_encrypt, box_decrypt

# 加密（需要发送方账户 + 接收方地址）
sender = Account.from_keystore("sender.json", "password")
ciphertext = box_encrypt("秘密消息", sender, "ak_recipient...")

# 解密（需要接收方账户 + 发送方地址）
recipient = Account.from_keystore("recipient.json", "password")
plaintext = box_decrypt(ciphertext, recipient, "ak_sender...")
```

### MessageCrypto 类

```python
from aeknow.crypto import MessageCrypto

# 初始化
crypto = MessageCrypto.from_keystore("wallet.json", "password")
# 或
crypto = MessageCrypto.from_mnemonic("your mnemonic words")

print(f"地址: {crypto.address}")
print(f"X25519 公钥: {crypto.x25519_public_hex}")

# 匿名加密（返回 Base64）
encrypted = crypto.sealed_encrypt("Hello", "ak_recipient...")
decrypted = crypto.sealed_decrypt(encrypted)

# 双向认证加密（返回 Base64）
encrypted = crypto.box_encrypt("Hello", "ak_recipient...")
decrypted = crypto.box_decrypt(encrypted, "ak_sender...")
```

### 密钥转换函数

```python
from aeknow.crypto import (
    ed25519_to_x25519_private,
    ed25519_to_x25519_public,
    account_to_x25519_keypair,
    address_to_x25519_public,
    get_key_info
)

# 获取账户密钥信息
info = get_key_info(account)
print(info)
# {
#     'address': 'ak_...',
#     'ed25519_public': '...',
#     'x25519_public': '...'
# }
```

---

## hashing - 哈希工具

编码、解码、哈希计算等底层工具函数。

### 编码/解码

```python
from aeknow.hashing import encode, decode
from aeknow.identifiers import ACCOUNT_ID

# 编码
raw_pubkey = bytes(32)  # 32 字节公钥
encoded = encode(ACCOUNT_ID, raw_pubkey)
print(encoded)  # ak_11111...

# 解码
raw_bytes = decode("ak_11111...")
```

### RLP 编码

```python
from aeknow.hashing import encode_rlp, decode_rlp
from aeknow.identifiers import TRANSACTION

# 编码
data = [b"hello", b"world"]
encoded = encode_rlp(TRANSACTION, data)

# 解码
decoded = decode_rlp(encoded)
```

### 哈希计算

```python
from aeknow.hashing import hash, hash_encode
from aeknow.identifiers import TRANSACTION_HASH

# 计算 blake2b 哈希
h = hash(b"data to hash")
print(h.hex())

# 计算并编码
encoded_hash = hash_encode(TRANSACTION_HASH, b"data to hash")
print(encoded_hash)  # th_...
```

### ID 相关函数

```python
from aeknow.hashing import name_id, contract_id, oracle_id, oracle_query_id, commitment_id

# 域名 ID
nm_id = name_id("example.chain")

# 合约 ID
ct_id = contract_id("ak_owner...", nonce=1)

# 预言机 ID
ok_id = oracle_id("ak_account...")

# 预言机查询 ID
oq_id = oracle_query_id("ak_sender...", nonce=1, oracle_id="ok_...")

# AENS 承诺 ID
cm_id, salt = commitment_id("example.chain")
```

### 随机数生成

```python
from aeknow.hashing import randint, randbytes

# 随机整数
n = randint(upper_bound=2**64)

# 随机字节
b = randbytes(size=32)
```

---

## node - 节点客户端

与 aeknow 节点交互的客户端。

### Config 配置类

```python
from aeknow.node import Config

config = Config(
    external_url='https://sdk-mainnet.aepps.com',  # 节点外部 URL
    internal_url='http://localhost:3113',           # 节点内部 URL（可选）
    force_compatibility=False,                      # 是否忽略版本检查
    blocking_mode=False,                            # 是否等待交易确认
    network_id=None,                                # 网络 ID（自动检测）
    # 交易参数
    tx_gas_per_byte=20,
    tx_base_gas=15000,
    tx_gas_price=1000000000,
    # 合约参数
    contract_gas=10000,
    contract_gas_price=1000000000,
    # 轮询参数
    poll_tx_max_retries=8,
    poll_tx_retries_interval=2,
)
```

### NodeClient 类

#### 初始化

```python
from aeknow.node import NodeClient, Config

# 使用默认配置（主网）
client = NodeClient()

# 自定义配置
config = Config(external_url='https://testnet.aeknow.io')
client = NodeClient(config)
```

#### 查询链状态

```python
# 获取顶部区块
top = client.get_top_block()
print(f"高度: {top.height}")

# 获取当前高度
height = client.get_current_key_block_height()

# 获取节点状态
status = client.get_status()
print(f"网络: {status.network_id}")
```

#### 账户操作

```python
# 获取账户信息
account = client.get_account("ak_...")
print(f"余额: {account.balance}")
print(f"Nonce: {account.nonce}")

# 获取余额
balance = client.get_balance("ak_...")

# 获取下一个 nonce
nonce = client.get_next_nonce("ak_...")
```

#### 转账

```python
from aeknow.signing import Account

sender = Account.from_keystore("sender.json", "password")

# 简单转账
tx = client.spend(
    account=sender,
    recipient_id="ak_recipient...",
    amount=1000000000000000000,  # 1 AE (in aettos)
    payload="转账备注"
)
print(f"交易哈希: {tx.hash}")

# 按百分比转账
tx = client.transfer_funds(
    account=sender,
    recipient_id="ak_recipient...",
    percentage=0.5,  # 转账 50%
    include_fee=True  # 从金额中扣除手续费
)
```

#### 交易操作

```python
# 签名交易
signed_tx = client.sign_transaction(account, unsigned_tx)

# 广播交易
tx_hash = client.broadcast_transaction(signed_tx)

# 获取交易
tx = client.get_transaction("th_...")

# 等待交易确认
block_height = client.wait_for_transaction("th_...")

# 等待多个区块确认
block_height = client.wait_for_confirmation("th_...")
```

#### 合约/域名/预言机

```python
# 创建合约对象
contract = client.Contract()

# 创建域名对象
name = client.AEName("example.chain")

# 创建预言机对象
oracle = client.Oracle()
```

---

## compiler - 编译器客户端

Sophia 合约编译器客户端。

### CompilerClient 类

```python
from aeknow.compiler import CompilerClient

# 使用默认编译器
compiler = CompilerClient()

# 指定编译器 URL
compiler = CompilerClient(compiler_url="https://v8.compiler.aepps.com")
```

#### 编译合约

```python
# 从源码编译
source_code = '''
@compiler >= 6
contract SimpleStorage =
  record state = { value : int }
  entrypoint init(v : int) = { value = v }
  entrypoint get() = state.value
  stateful entrypoint set(v : int) = put(state{ value = v })
'''

bytecode = compiler.compile(source_code)
print(bytecode)  # cb_...
```

#### 生成 Calldata

```python
# 生成初始化 calldata
init_calldata = compiler.encode_calldata(source_code, "init", ["42"])

# 生成调用 calldata
call_calldata = compiler.encode_calldata(source_code, "set", ["100"])
```

#### 解码返回值

```python
# 解码调用结果
result = compiler.decode_call_result(source_code, "get", call_result_data)
print(result)  # 42
```

#### 获取 ACI

```python
# 获取合约接口
aci = compiler.generate_aci(source_code)
print(aci)
```

---

## contract - 合约模块

低级合约操作模块。

### Contract 类

```python
from aeknow.node import NodeClient
from aeknow.signing import Account

client = NodeClient()
contract = client.Contract()

account = Account.from_keystore("wallet.json", "password")
```

#### 部署合约

```python
tx = contract.create(
    account=account,
    bytecode="cb_...",       # 编译后的字节码
    calldata="cb_...",       # init 函数 calldata
    amount=0,                # 转入合约的金额
    gas=100000,              # Gas 限制
    gas_price=1000000000     # Gas 价格
)

contract_id = tx.metadata.get("contract_id")
print(f"合约地址: {contract_id}")
```

#### 调用合约

```python
tx = contract.call(
    contract_id="ct_...",
    account=account,
    function="set",
    calldata="cb_...",
    amount=0,
    gas=100000
)
```

#### 静态调用（不上链）

```python
result = contract.call_static(
    contract_id="ct_...",
    function="get",
    calldata="cb_..."
)
print(result.return_value)
```

#### 获取调用结果

```python
call_object = contract.get_call_object("th_...")
print(call_object.return_value)
```

#### 检查合约是否部署

```python
is_deployed = contract.is_deployed("ct_...")
```

---

## contract_native - 原生合约管理

高级合约管理器，自动处理编译、部署、调用。

### ContractManager 类

```python
from aeknow.contract_native import ContractManager
from aeknow.node import NodeClient
from aeknow.signing import Account

client = NodeClient()
account = Account.from_keystore("wallet.json", "password")
```

#### 从源码创建

```python
source_code = open("contract.aes").read()

manager = ContractManager(
    client=client,
    account=account,
    source=source_code
)
```

#### 从已部署合约创建

```python
manager = ContractManager(
    client=client,
    account=account,
    contract_id="ct_...",
    source=source_code
)
```

#### 部署合约

```python
# 带初始参数部署
tx = manager.deploy("42")  # init(42)

print(f"合约地址: {manager.contract_id}")
```

#### 调用合约函数

```python
# 写入调用（上链）
tx = manager.call("set", "100")
print(f"交易: {tx.hash}")

# 读取调用（不上链）
result = manager.call_static("get")
print(f"结果: {result}")
```

#### 解码事件

```python
# 获取交易事件
events = manager.get_events("th_...")
for event in events:
    print(f"事件: {event}")
```

---

## transactions - 交易构建

底层交易构建模块，用于创建各类交易。

### TxBuilder 类

```python
from aeknow.transactions import TxBuilder

txb = TxBuilder(
    base_gas=15000,
    gas_per_byte=20,
    gas_price=1000000000,
    key_block_interval=3
)
```

#### 构建 Spend 交易

```python
tx = txb.tx_spend(
    sender_id="ak_sender...",
    recipient_id="ak_recipient...",
    amount=1000000000000000000,
    payload="备注",
    fee=0,  # 自动计算
    ttl=0,
    nonce=1
)
```

#### 构建合约创建交易

```python
tx = txb.tx_contract_create(
    owner_id="ak_...",
    code="cb_...",
    calldata="cb_...",
    amount=0,
    deposit=0,
    gas=100000,
    gas_price=1000000000,
    vm_version=8,
    abi_version=3,
    fee=0,
    ttl=0,
    nonce=1
)
```

#### 构建合约调用交易

```python
tx = txb.tx_contract_call(
    caller_id="ak_...",
    contract_id="ct_...",
    calldata="cb_...",
    function="set",
    amount=0,
    gas=100000,
    gas_price=1000000000,
    abi_version=3,
    fee=0,
    ttl=0,
    nonce=1
)
```

### TxSigner 类

```python
from aeknow.transactions import TxSigner
from aeknow.signing import Account

account = Account.generate()
signer = TxSigner(account, network_id="ae_mainnet")

# 签名交易
signature = signer.sign_transaction(tx)
```

### TxObject 类

交易对象，包含交易数据和元信息。

```python
# 属性
tx.tx        # 编码后的交易字符串
tx.hash      # 交易哈希 (th_...)
tx.data      # 交易数据对象
tx.metadata  # 元数据字典
```

---

## aens - 域名服务

aeknow 域名服务 (AENS) 模块。

### AEName 类

```python
from aeknow.node import NodeClient
from aeknow.signing import Account

client = NodeClient()
account = Account.from_keystore("wallet.json", "password")

# 创建域名对象
name = client.AEName("example.chain")
```

#### 检查域名状态

```python
# 更新状态
name.update_status()
print(name.status)  # AVAILABLE / CLAIMED / PRECLAIMED

# 检查是否可用
if name.is_available():
    print("域名可注册")

# 检查是否已注册
if name.check_claimed():
    print(f"TTL: {name.name_ttl}")
    print(f"指针: {name.pointers}")
```

#### 完整注册流程（阻塞模式）

```python
# 一键注册（预注册 -> 注册 -> 更新指针）
hashes = name.full_claim_blocking(
    account,
    account.get_address(),  # 指向账户
    name_ttl=50000,
    client_ttl=84600
)
print(hashes['preclaim_tx'].hash)
print(hashes['claim_tx'].hash)
print(hashes['update_tx'].hash)
```

#### 分步注册

```python
# Step 1: 预注册
preclaim_tx = name.preclaim(account)
print(f"预注册: {preclaim_tx.hash}")

# 等待确认...
client.wait_for_confirmation(preclaim_tx.hash)

# Step 2: 注册
claim_tx = name.claim(
    preclaim_tx.hash,
    account,
    preclaim_tx.metadata['salt']
)
print(f"注册: {claim_tx.hash}")

# 等待确认...
client.wait_for_confirmation(claim_tx.hash)

# Step 3: 更新指针
update_tx = name.update(
    account,
    account.get_address()  # 指向账户
)
```

#### 更新域名指针

```python
# 指向账户
name.update(account, "ak_...")

# 指向合约
name.update(account, "ct_...")

# 指向预言机
name.update(account, "ok_...")

# 多个指针
name.update(account, "ak_...", "ct_...")

# 自定义指针
name.update(account, ("custom_key", "ak_..."))
```

#### 转让域名

```python
transfer_tx = name.transfer_ownership(
    account,
    recipient_id="ak_new_owner..."
)
```

#### 撤销域名

```python
revoke_tx = name.revoke(account)
```

#### 计算费用

```python
from aeknow.aens import AEName

# 获取最低注册费
min_fee = AEName.get_minimum_name_fee("example.chain")
print(f"最低费用: {min_fee} aettos")

# 计算竞价费（+5%）
bid_fee = AEName.compute_bid_fee("example.chain", start_fee=min_fee)

# 计算拍卖结束区块
end_block = AEName.compute_auction_end_block("example.chain", claim_height=1000)
```

### NameStatus 枚举

```python
from aeknow.aens import NameStatus

NameStatus.AVAILABLE   # 可用
NameStatus.PRECLAIMED  # 已预注册
NameStatus.CLAIMED     # 已注册
NameStatus.REVOKED     # 已撤销
NameStatus.UNKNOWN     # 未知
```

---

## oracles - 预言机

aeknow 预言机模块。

### Oracle 类

```python
from aeknow.node import NodeClient
from aeknow.signing import Account

client = NodeClient()
account = Account.from_keystore("wallet.json", "password")
oracle = client.Oracle()
```

#### 注册预言机

```python
tx = oracle.register(
    account,
    query_format="string",        # 查询格式
    response_format="string",     # 响应格式
    query_fee=0,                  # 查询费用
    ttl_type='delta',             # TTL 类型
    ttl_value=500                 # TTL 值
)

print(f"预言机 ID: {oracle.id}")  # ok_...
```

#### 响应查询

```python
tx = oracle.respond(
    account,
    query_id="oq_...",
    response="Response data"
)
```

#### 延长 TTL

```python
tx = oracle.extend(
    account,
    query_id="oq_...",
    response="",
    ttl_value=500
)
```

### OracleQuery 类

```python
# 创建查询对象
query = client.OracleQuery(oracle_id="ok_...")

# 执行查询
tx = query.execute(
    sender=account,
    query="What is the price of AE?",
    query_fee=1000,
    query_ttl_value=10,
    response_ttl_value=10
)

print(f"查询 ID: {query.id}")  # oq_...

# 获取响应
response = query.get_response_object()
print(response)
```

---

## utils - 工具函数

通用工具函数集合。

### 验证函数

```python
from aeknow.utils import is_valid_hash, is_valid_aens_name, prefix_match

# 验证哈希
is_valid = is_valid_hash("ak_...")  # True
is_valid = is_valid_hash("ak_...", prefix="ak")  # True
is_valid = is_valid_hash("th_...", prefix="ak")  # False

# 验证域名
is_valid = is_valid_aens_name("example.chain")  # True
is_valid = is_valid_aens_name("example.com")    # False

# 前缀匹配
match = prefix_match("ak", "ak_123")  # True
```

### 金额转换

```python
from aeknow.utils import amount_to_aettos, format_amount

# 转换为 aettos
aettos = amount_to_aettos(1)        # 1 aetto
aettos = amount_to_aettos(1.5)      # 1.5e18 aettos
aettos = amount_to_aettos("1AE")    # 1e18 aettos
aettos = amount_to_aettos("1.5ae")  # 1.5e18 aettos

# 格式化金额
formatted = format_amount(1000000000000000000)  # "1AE"
formatted = format_amount(1500000000000000000)  # "1.5AE"
formatted = format_amount(1000000, -6, "microAE")  # "1microAE"
```

---

## defaults - 默认配置

SDK 默认参数配置。

```python
from aeknow import defaults

# Gas 相关
defaults.BASE_GAS           # 15000
defaults.GAS_PER_BYTE       # 20
defaults.GAS_PRICE          # 1000000000 (1 Gwei)

# 交易
defaults.TX_TTL             # 0 (最大 TTL)
defaults.FEE                # 0 (自动计算)

# 合约
defaults.CONTRACT_GAS       # 10000
defaults.CONTRACT_GAS_PRICE # 1000000000
defaults.CONTRACT_DEPOSIT   # 0
defaults.CONTRACT_AMOUNT    # 0

# 预言机
defaults.ORACLE_TTL_TYPE    # 'delta'
defaults.ORACLE_TTL_VALUE   # 500
defaults.ORACLE_QUERY_FEE   # 0

# 域名
defaults.NAME_MAX_TTL       # 50000 blocks
defaults.NAME_FEE           # 0
defaults.NAME_BID_RANGES    # {长度: 费用} 映射

# 链参数
defaults.KEY_BLOCK_INTERVAL         # 3 分钟
defaults.KEY_BLOCK_CONFIRMATION_NUM # 3 个区块

# 轮询
defaults.POLL_TX_MAX_RETRIES      # 8
defaults.POLL_TX_RETRIES_INTERVAL # 2 秒

# 编译器
defaults.COMPILER_URL  # "https://v8.compiler.aepps.com"

# Dry Run
defaults.DRY_RUN_ADDRESS  # 测试地址
defaults.DRY_RUN_AMOUNT   # 测试金额
```

---

## identifiers - 标识符常量

各类 ID 前缀和协议常量。

### ID 前缀 (Base58)

```python
from aeknow import identifiers

identifiers.ACCOUNT_ID        # "ak" - 账户
identifiers.CONTRACT_ID       # "ct" - 合约
identifiers.ORACLE_ID         # "ok" - 预言机
identifiers.ORACLE_QUERY_ID   # "oq" - 预言机查询
identifiers.NAME_ID           # "nm" - 域名
identifiers.CHANNEL_ID        # "ch" - 通道
identifiers.TRANSACTION_HASH  # "th" - 交易哈希
identifiers.KEY_BLOCK_HASH    # "kh" - 关键块哈希
identifiers.MICRO_BLOCK_HASH  # "mh" - 微块哈希
identifiers.COMMITMENT_ID     # "cm" - 承诺
identifiers.SIGNATURE         # "sg" - 签名
```

### ID 前缀 (Base64)

```python
identifiers.BYTECODE          # "cb" - 合约字节码
identifiers.TRANSACTION       # "tx" - 交易
identifiers.BYTE_ARRAY        # "ba" - 字节数组
identifiers.ORACLE_QUERY      # "ov" - 预言机查询
identifiers.ORACLE_RESPONSE   # "or" - 预言机响应
```

### 账户地址格式

```python
identifiers.ACCOUNT_API_FORMAT    # 'api' - ak_xxx
identifiers.ACCOUNT_SOFIA_FORMAT  # 'sofia' - 0x...
identifiers.ACCOUNT_RAW_FORMAT    # 'raw' - bytes
```

### VM/ABI 版本

```python
identifiers.VM_FATE_3   # 8 (Ceres)
identifiers.ABI_FATE    # 3

# 协议版本映射
identifiers.PROTOCOL_ABI_VM[identifiers.PROTOCOL_CERES]
# {'vm': 8, 'abi': 3}
```

### 网络 ID

```python
identifiers.NETWORK_ID_MAINNET  # "ae_mainnet"
identifiers.NETWORK_ID_TESTNET  # "ae_uat"
```

### 账户类型

```python
identifiers.ACCOUNT_KIND_BASIC       # "basic"
identifiers.ACCOUNT_KIND_GENERALIZED # "generalized"
```

### Keystore 类型

```python
identifiers.SECRET_TYPE_BIP39     # "ed25519-bip39-mnemonic"
identifiers.SECRET_TYPE_SLIP0010  # "ed25519-slip0010-masterkey"
```

---

## 异常类型

```python
from aeknow.exceptions import (
    TransactionWaitTimeoutExpired,  # 交易等待超时
    TransactionHashMismatch,        # 交易哈希不匹配
    NameNotAvailable,               # 域名不可用
    MissingPreclaim,                # 缺少预注册
    NameUpdateError,                # 域名更新错误
    NameTooEarlyClaim,              # 过早注册
    NameCommitmentIdMismatch,       # 承诺 ID 不匹配
    UnsupportedNodeVersion,         # 节点版本不支持
)
```

---

## 完整示例

### 创建钱包并保存

```python
from aeknow.wallet import MnemonicWallet

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

print(f"助记词: {wallet.mnemonic}")
print(f"地址: {wallet.address}")

# 保存 Keystore
wallet.save_keystore("my_wallet.json", "secure_password")
```

### 转账 AE

```python
from aeknow.node import NodeClient, Config
from aeknow.signing import Account

client = NodeClient(Config(external_url='https://sdk-mainnet.aepps.com'))
account = Account.from_keystore("wallet.json", "password")

# 转账 1 AE
tx = client.spend(
    account=account,
    recipient_id="ak_recipient...",
    amount="1AE",
    payload="Payment"
)

print(f"交易哈希: {tx.hash}")
```

### 部署和调用合约

```python
from aeknow.node import NodeClient
from aeknow.signing import Account
from aeknow.contract_native import ContractManager

client = NodeClient()
account = Account.from_keystore("wallet.json", "password")

source = '''
@compiler >= 6
contract Counter =
  record state = { count : int }
  entrypoint init(n : int) = { count = n }
  entrypoint get() = state.count
  stateful entrypoint add(n : int) = put(state{ count = state.count + n })
'''

manager = ContractManager(client=client, account=account, source=source)

# 部署
tx = manager.deploy("0")  # init(0)
print(f"合约地址: {manager.contract_id}")

# 调用
tx = manager.call("add", "10")
result = manager.call_static("get")
print(f"Count: {result}")
```

### 消息签名和验证

```python
from aeknow.message import sign_message, verify_message
from aeknow.signing import Account

account = Account.generate()

# 签名
signature = sign_message(account, "Hello aeknow!")

# 验证
is_valid = verify_message(account.get_address(), "Hello aeknow!", signature)
print(f"签名有效: {is_valid}")
```

### 加密通信

```python
from aeknow.crypto import MessageCrypto
from aeknow.signing import Account

# Alice 和 Bob 的账户
alice = Account.generate()
bob = Account.generate()

alice_crypto = MessageCrypto.from_account(alice)
bob_crypto = MessageCrypto.from_account(bob)

# Alice 发送加密消息给 Bob
encrypted = alice_crypto.box_encrypt("Secret message", bob.get_address())

# Bob 解密消息
decrypted = bob_crypto.box_decrypt(encrypted, alice.get_address())
print(decrypted)  # "Secret message"
```

---

## 版本兼容性

| SDK 版本 | 节点版本 | 编译器版本 |
|----------|----------|------------|
| 当前 | >=5.0.0, <=8.0.0 | >=4.1.0, <9.0.0 |

---

## License

MIT License


