核心

AENS 域名系统

Æternity 命名系统的完整生命周期管理

概述

本指南展示如何使用 SDK 执行 Æternity 命名系统 (AENS) 生命周期中的所有操作。

重要:成功认领的域名将在 180,000 个关键区块(约 375 天)后过期。你需要在过期前更新域名!
1 认领域名 (Claim)

认领 AENS 域名需要至少 2 笔交易:

预认领 (Pre-claim)

提交 commitmentId(哈希值),由随机 salt 和域名计算得出。SDK 会自动生成 salt 并计算 commitmentId。

认领 (Claim)

预认领交易上链后,执行实际认领。根据域名长度,可能立即获得所有权或启动竞价。

Pre-claim 预认领
import { AeSdk, Name } from '@aeternity/aepp-sdk';

const aeSdk = new AeSdk({ ... }); // 初始化 SDK

// getContext() 用于绑定 AeSdk 到 Name 实例
const name = new Name('myname.chain', aeSdk.getContext());

const preClaimTx = await name.preclaim();
console.log(preClaimTx);
/*
{
  blockHeight: 449499,
  hash: 'th_48RktjEutZC8TCubaq9YhjaF1cKLV9D3VRCJyzJLs7oSp4Ry6',
  tx: {
    accountId: 'ak_...',
    commitmentId: 'cm_...',
    type: 'NamePreclaimTx',
    ...
  }
}
*/
注意:
  • 交易上链后,有 300 个关键区块的时间窗口执行 claim
  • 为防止抢注,建议等待至少 1 个区块后再执行 claim
  • 协议不会拒绝已被认领域名的 pre-claim,请先检查域名可用性
Claim 认领

根据域名(punycode)长度决定结果:

  • 长度 > 12:立即获得所有权
  • 长度 ≤ 12:启动竞价拍卖
// SDK 自动计算最低 nameFee
// 如需自定义,可通过选项传入
const claimTx = await name.claim();
console.log(claimTx);
/*
{
  blockHeight: 449507,
  hash: 'th_2sWNusGUf2wuRn7d453wPWTAe8pKVbtNF4DqakvippsxjvF8g1',
  tx: {
    name: 'myname.chain',
    nameFee: 2865700000000000000n,
    type: 'NameClaimTx',
    ...
  }
}
*/
竞价出价

如果域名处于拍卖中,需要出价竞标:

import { computeBidFee, computeAuctionEndBlock } from '@aeternity/aepp-sdk';

const name = new Name('short.chain', aeSdk.getContext());

const startFee = ...; // 从中间件获取当前最高出价
const increment = 0.05; // 5%,最低加价幅度

// 计算出价金额
const nameFee = computeBidFee(name.value, { startFee, increment });
const bidTx = await name.bid(nameFee);

console.log(`出价区块: ${bidTx.blockHeight}`);
console.log(`拍卖结束区块: ${computeAuctionEndBlock(name.value, bidTx.blockHeight)}`);
竞价规则:
  • 每次出价必须比当前最高价高 至少 5%
  • 赢得拍卖后,nameFee 永久销毁(转入无人可访问的地址)
  • 被超过时,你的出价会立即退还
2 更新域名 (Update)

拥有域名后,你可以:

  • 设置指向 账户预言机合约通道 的指针,或存储二进制数据
  • 延长 TTL 以防过期(最长 180,000 区块)
设置指针和更新 TTL
import { getDefaultPointerKey, encode, Encoding } from '@aeternity/aepp-sdk';

const oracle = 'ok_...';
const pointers = {
  account_pubkey: 'ak_...', // 账户指针
  oracle_pubkey: oracle,     // 预言机指针
  contract_pubkey: 'ct_...', // 合约指针
  channel: 'ch_...',         // 通道指针
  customKey: encode(Buffer.from('自定义数据'), Encoding.Bytearray),
};

const nameUpdateTx = await name.update(pointers);
console.log(nameUpdateTx);
指针行为:
  • 传空对象且不设置 extendPointers: true 会清除所有指针
  • 使用 extendPointers 会合并现有指针和新指针
仅延长 TTL(保留指针)
// 延长到 100000 个区块
const nameUpdateTx = await name.extendTtl(100000);
console.log(nameUpdateTx);
3 转让所有权 (Transfer)

将域名所有权转让给另一个账户:

const recipient = 'ak_...'; // 接收方地址
const nameTransferTx = await name.transfer(recipient);
console.log(nameTransferTx);
/*
{
  tx: {
    recipientId: 'ak_...',
    nameId: 'nm_...',
    type: 'NameTransferTx',
    ...
  }
}
*/
4 撤销域名 (Revoke)

在过期前主动撤销域名:

const nameRevokeTx = await name.revoke();
console.log(nameRevokeTx);
/*
{
  tx: {
    nameId: 'nm_...',
    type: 'NameRevokeTx',
    ...
  }
}
*/
注意:
  • 撤销后域名进入 revoked 状态
  • 经过 2016 个关键区块后,域名可被再次认领
委托签名给合约 (AENS Interface)

可以授权 Sophia 合约代表你的账户管理 AENS 域名。这可用于构建 AENS 市场等应用。

import { packDelegation, DelegationTag } from '@aeternity/aepp-sdk';

const contractAddress = 'ct_...';
const nameId = 'example.chain';

const commonParams = {
  contractAddress,
  accountAddress: aeSdk.address,
};

// 授权合约执行 pre-claim
let delegation = packDelegation({ 
  tag: DelegationTag.AensPreclaim, 
  ...commonParams 
});

// 授权合约管理特定域名的所有操作
delegation = packDelegation({ 
  tag: DelegationTag.AensName, 
  nameId, 
  ...commonParams 
});

// 授权合约管理你拥有的所有域名(通配符)
delegation = packDelegation({ 
  tag: DelegationTag.AensWildcard, 
  ...commonParams 
});

// 生成委托签名
const delegationSignature = await aeSdk.signDelegation(delegation);
快速参考
操作 方法 说明
预认领 name.preclaim() 提交承诺哈希
认领 name.claim() 认领或启动拍卖
出价 name.bid(fee) 拍卖中出价
更新 name.update(pointers) 设置指针
延长 name.extendTtl(ttl) 延长有效期
转让 name.transfer(recipient) 转让所有权
撤销 name.revoke() 放弃域名