跳转到内容

账户

Aptos 上的账户控制一组链上资产,包括同质化资产、Coin 和数字资产(NFT)。这些资产是资源:一种强制访问控制和稀缺性的 Move 原语。

每个账户由 32 字节地址标识。你可以使用 Aptos 名称服务 为重要账户注册易读的 .apt 域名。

与账户仅为“带余额的地址”的链不同,Aptos 账户是显式的,并由链上资源支撑,因而支持密钥轮转和原生多重签名。不过,有了无状态账户(AIP-115),你不再需要先创建账户才能使用它。任何有效地址默认都视为账户,只要持有私钥即可发送交易。链上 Account 资源仅在首次需要时自动创建(例如轮换密钥时)。地址如何派生见创建账户

Aptos 账户提供大多数其他网络没有的能力:

  • 密钥轮转。 账户的认证密钥可以改为由另一把私钥控制,类似于更换密码。
  • 原生多重签名。 账户支持使用 Ed25519 和 Secp256k1 ECDSA 的 k-of-n 多重签名。

Aptos 上有三类账户:

  • 标准账户 — 由公钥/私钥对控制的地址。该密钥对可以是 Ed25519、Secp256k1、Keyless、WebAuthn 或 k-of-n 组合。
  • 资源账户 — 没有交互式私钥的自主账户,用于存储资源或发布模块。
  • 对象 — 将资源组合为一个实体的专用地址。
Alice: 0xeeff357ea5c1a4e7bc11b2b17ff2dc2dcca69750bfef1e1ebcaccf8c8018175b
Bob: 0x19aadeca9388e009d136245b9a67423f3eee242b03142849eb4f81a4a409e59c

Aptos 使用单一标识符表示账户:32 字节十六进制字符串。短于32字节的十六进制字符串也是有效的;在这些情况下,十六进制字符串可以用前导零填充,例如,0x1 => 0x0000000000000...01。虽然Aptos标准表明可以从地址中删除前导零,但大多数应用程序试图避免这种遗留行为,仅支持为从0x00xa的特殊地址删除0。

当用户请求创建账户时,例如通过使用Aptos SDK,将执行以下步骤:

  • 选择用于管理用户账户的认证方案,例如Ed25519或Secp256k1 ECDSA。
  • 生成新的私钥、公钥对。
  • 将公钥与公钥的认证方案结合以生成32字节认证密钥和账户地址。

用户应使用私钥对与此账户关联的交易进行签名。

账户的序列号表示从该账户提交并在链上确认的有序交易数量。已提交的交易要么执行并将状态变更写入区块链,要么中止(丢弃状态变更,只存储交易)。

每笔有序交易必须携带发送者的下一个序列号。节点将该数字与链上账户比较。只有从当前序列号起能形成连续序列时,内存池才会转发交易。执行会拒绝空缺,从而防止重放过旧交易并为后续交易排序。

无序交易不使用该计数器。它们改用唯一 nonce,将 sequence_number 设为 u64::MAX,并在 60 秒内过期。这样多台机器可以从同一账户提交交易而无需协调序列号。详见 AIP-123

初始账户地址设置为在账户创建期间派生的认证密钥。认证密钥之后可以更改,例如轮换到新的密钥对。账户地址永不更改。

Aptos区块链支持以下认证方案:

  1. Ed25519
  2. Secp256k1 ECDSA
  3. K-of-N多重签名
  4. 专用的、现在已遗留的MultiEd25519方案

为Ed25519签名生成认证密钥和账户地址:

  1. 生成密钥对:生成一个新的密钥对(privkey_A, pubkey_A)。Aptos区块链使用RFC 8032中定义的Ed25519曲线上的PureEdDSA方案。
  2. 派生32字节认证密钥:从pubkey_A派生32字节认证密钥:
    auth_key = sha3-256(pubkey_A | 0x00)
    其中|表示连接。0x00是1字节单签名方案标识符。
  3. 使用此初始认证密钥作为永久账户地址。

使用K-of-N多重签名认证,账户总共有N个签名者,必须使用其中至少K个签名来认证交易。

生成K-of-N多重签名账户的认证密钥和账户地址:

  1. 生成密钥对:生成N个ed25519公钥p_1, …, p_n
  2. 决定K的值,即认证交易所需的签名阈值数量。
  3. 派生32字节认证密钥:如下所述计算认证密钥:
    auth_key = sha3-256(p_1 | . . . | p_n | K | 0x01)
    0x01是1字节多重签名方案标识符。
  4. 使用此初始认证密钥作为永久账户地址。

通用认证支持Ed25519和Secp256k1 ECDSA。与之前的认证方案一样,这些方案包含方案值,单密钥和多密钥分别为0x020x03,但每个密钥都包含一个前缀值来指示其密钥类型:

密钥类型前缀字节
Ed25519通用方案0x00
Secp256k1Ecdsa通用方案0x01
Secp256r1Ecdsa WebAuthn方案0x02
无密钥0x03

对于使用公钥pubkey的单密钥Secp256k1 ECDSA账户,认证密钥将如下派生:

auth_key = sha3-256(0x01 | pubkey | 0x02)

其中

  • 第一个条目0x01代表使用Secp256k1 ECDSA密钥;
  • 最后一个条目0x02代表认证方案。

对于包含单个Secp256k1 ECDSA公钥pubkey_0和单个Ed25519公钥pubkey_1的1-of-2多密钥账户,其中一个签名就足够了,认证密钥将如下派生:

auth_key = sha3-256(0x02 | 0x01 | pubkey_0 | 0x00 | pubkey_1 | 0x01 | 0x03)

其中

  • 第一个条目0x02代表作为单字节的密钥总数;
  • 倒数第二个条目0x01代表作为单字节的所需签名数量;
  • 最后一个条目0x03代表认证方案。

Aptos上的账户具有轮换密钥的能力,这样潜在泄露的密钥就不能用于访问账户。可以通过account::rotate_authentication_key函数轮换密钥。

刷新密钥通常被认为是安全领域的良好习惯。但是,这对习惯于使用助记词来表示私钥及其关联账户的系统集成商来说是一个挑战。为了简化系统集成商的工作,Aptos 通过 aptos account lookup-address 提供链上映射。链上数据将由当前助记词定义的有效账户地址映射到实际账户地址。

有关更多信息,请参阅 account.move

每个账户的状态包括代码(Move模块)和数据(Move资源)。账户可能包含任意数量的Move模块和Move资源:

  • Move模块:Move模块包含代码,例如类型和过程声明;但它们不包含数据。Move模块编码了更新Aptos区块链全局状态的规则。
  • Move资源:Move资源包含数据但不包含代码。每个资源值都有一个在Aptos区块链上发布的模块中声明的类型。

交易的发送者由签名者表示。当Move模块中的函数将signer作为参数时,Aptos Move VM将签署交易的账户身份转换为Move模块入口点中的签名者。请参阅下面带有signer的Move示例代码,在initializewithdraw函数中。当函数中未指定signer时,例如下面的deposit函数,则不会为此函数提供基于签名者的访问控制:

module Test::Coin {
struct Coin has key { amount: u64 }
public fun initialize(account: &signer) {
move_to(account, Coin { amount: 1000 });
}
public fun withdraw(account: &signer, amount: u64): Coin acquires Coin {
let balance = &mut borrow_global_mut<Coin>(Signer::address_of(account)).amount;
*balance = *balance - amount;
Coin { amount }
}
public fun deposit(account: address, coin: Coin) acquires Coin {
let balance = &mut borrow_global_mut<Coin>(account).amount;
*balance = *balance + coin.amount;
Coin { amount: _ } = coin;
}
}