> For the complete documentation index, see [llms.txt](https://gushi10546.gitbook.io/aptos-kai-fa-zhe-wen-dang/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gushi10546.gitbook.io/aptos-kai-fa-zhe-wen-dang/gai-nian/zhang-hu.md).

# 帐户

## **帐户**

Aptos 区块链上的帐户包含区块链资产。这些资产，例如代币和 NFT，本质上是稀缺的，必须由访问控制。任何此类资产在区块链帐户中都表示为**资源**。资源是 Move 语言原语，在其表示中强调访问控制和稀缺性。然而，资源也可以用于代表其他链上功能、识别信息和访问控制。

Aptos 区块链上的每个帐户都由 32 字节的帐户地址标识。帐户可以存储数据，并将这些数据存储在资源中。初始资源是帐户数据本身（身份验证密钥和序列号）。创建帐户后，将添加货币或 NFT 等其他资源。

💡 **帐户地址示例**

帐户地址为 32 字节。它们通常显示为 64 个十六进制字符，每个十六进制字符都是半字节。有关地址显示的示例，请参阅发起第一笔交易：

`Alice: eeff357ea5c1a4e7bc11b2b17ff2dc2dcca69750bfef1e1ebcaccf8c8018175b Bob: 19aadeca9388e009d136245b9a67423f3eee242b03142849eb4f81a4a409e59c`

### 创建一个帐户

当用户请求创建帐户时，例如使用 [Aptos SDK](https://aptos-labs.github.io/ts-sdk-doc/classes/AptosAccount.html)，将执行以下加密步骤：

* 首先生成一个新的私钥和公钥对。
* 从用户那里获得帐户的首选签名方案：帐户应使用单个签名还是需要多个签名才能签署交易。
* 将公钥和用户的签名方案相结合，生成 32 字节的身份验证密钥。
* 将帐户序列号初始化为 0.身份验证密钥和序列号都作为初始帐户资源存储在帐户中。
* 从初始身份验证密钥创建 32 字节的帐户地址。

从现在开始，用户应该使用私钥来签署该帐户的交易。

### 帐户序列号

帐户的序列号表示从该帐户在链上提交和承诺的交易数量。每当从该帐户发送的事务执行或中止并存储在区块链中时，它都会增加。

提交的每笔交易都必须包含发件人帐户的当前序列号。当 Aptos 区块链处理事务时，它会查看事务中的序列号，并将其与帐户中的序列号进行比较（存储在当前分类账版本的区块链上）。只有当事务中的序列号与发送方帐户的序列号相同时，才会执行事务，如果它们不匹配，则拒绝。这样，过去的交易必然包含旧的序列号，无法重放，从而防止重放攻击。

这些交易将保存在 mempool 中，直到它们成为该帐户的下一个序列号（或直到它们过期）。应用交易时，帐户的序列号将增加 1。该帐户的序列号严格增加。

### 帐户地址

在创建新帐户的过程中，首先会出现 32 字节的身份验证密钥。然后返回此身份验证密钥，因为它是 32 字节的帐户地址。

但是，身份验证密钥随后可能会发生变化，例如，当您生成一对新的私钥公钥来旋转密钥时。但帐户地址不会更改。因此，**仅在最初**32字节的身份验证密钥将与 32 字节的帐户地址相同。创建帐户后，即使私钥、公钥和身份验证密钥可能会更改，帐户地址仍将保持不变。无法更改现有帐户的地址。

### 签名方案

帐户可以发送交易。Aptos 区块链支持以下签名方案：

1. 用于单个签名的 [Ed25519](https://ed25519.cr.yp.to/)，以及
2. 用于多重签名的 MultiEd25519

{% hint style="info" %}
**注意** Aptos 区块链默认为单签名交易。
{% endhint %}

### 签名方案标识符

为帐户生成身份验证密钥需要您为该帐户提供以下 1 字节签名方案标识符之一，即无论该帐户是单个签名还是multisig帐户：

* **1 字节单签方案标识符：**`0x00`
* **1 字节多签方案标识符：**`0x01`。确保提供 K 的值来生成 N 分之 K 多签验证密钥。

### 单签验证

要生成单个签名帐户的身份验证密钥和帐户地址：

1. **生成密钥对：**&#x751F;成全新的密钥对（`privkey_A`, `pubkey_A`）。Aptos 区块链在 RFC 8032 中定义的 Ed25519 曲线上使用 PureEdDSA 方案。
2. 衍生 32 字节的身份验证密钥：从 `pubkey_A` 衍生出的 32 字节身份验证密钥，其中 `|` 表示串联。0x00是1字节的单签名方案标识符。

   ```
   auth_key = sha3-256(pubkey_A | 0x00)
   ```
3. 使用此初始身份验证密钥作为永久帐户地址。

### 多签验证

使用 K-of-N 多签身份验证，帐户共有 N 个签名人，其中须有至少 K 个签名用于验证交易。

要生成一个 K-of-N 的多签帐户的验证密钥和帐户地址：

1. **生成密钥对：**&#x751F;成 `N` 个 ed25519 公钥  `p_1`, ..., `p_n`
2. 决定 `K` 的值，`K` 是验证交易所需的签名阈值。
3. **衍生 32 字节的身份验证密钥：**&#x8BA1;算身份验证密钥如下所述：`0x01`是 1 字节多签方案标识符

   ```
   auth_key = sha3-256(p_1 | . . . | p_n | K | 0x01)
   ```
4. 使用此初始身份验证密钥作为永久帐户地址。

💡 **APTOS 测试网上的帐户**

为创建帐户，Aptos 测试网需要帐户的公钥和一定数量的 `Coin<TestCoin>` 添加到该帐户中，从而使用这两种资源创建一个新帐户。

### 通过签名者控制访问

交易的发送方由签名者表示。当 Move 模块中的函数将 `signer` 作为参数时，Aptos Move 虚拟机将签名交易的帐户的身份转换为 Move 模块入口点中的签名者。请参阅以下在 `initialize` 和 `withdraw` 函数中的 `signer` Move 示例代码。当函数中没有指定 `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;
  }
}
```

### 帐户状态

每个帐户的状态包括代码（Move 模块）和数据（Move 资源）。帐户可能包含任意数量的 Move 模块和 Move 资源：

* **Move 模块**：Move 模块包含代码，例如类型和过程声明，但它们不包含数据。Move 模块编码更新Aptos区块链全局状态的规则。
* **Move 资源**：Move 资源包含数据，但没有代码。每个资源值都有一个类型，该类型在 Aptos 区块链分布式数据库中发布的模块中声明。
