账户
Aptos 区块链上的账户包含区块链资产。这些资产,例如代币和 NFT,本质上是稀缺的,必须受到访问控制。任何此类资产在区块链账户中都表示为资源。资源是一种 Move 语言术语,在其表示中强调访问控制和稀缺性。但是,资源也可用于表示其他链上功能、识别信息和访问权限控制。
Aptos 区块链上的每个账户都由一个 32 字节的账户地址标识。帐户可以存储数据,并将此数据存储在资源中。初始资源是帐户数据本身(身份验证密钥和序列号)。创建帐户后会添加其他资源,例如 Coin 或 NFT。
帐户地址为 32 字节。它们通常显示为 64 个十六进制字符,每个十六进制字符都是一个半字节。有时它以 0x 为前缀,请参阅 Your First Transaction 以了解地址的外观示例,转载如下:
Alice: 0xeeff357ea5c1a4e7bc11b2b17ff2dc2dcca69750bfef1e1ebcaccf8c8018175b
Bob: 0x19aadeca9388e009d136245b9a67423f3eee242b03142849eb4f81a4a409e59c
如果有前边有 0,则可能会被省略:
Dan: 0000357ea5c1a4e7bc11b2b17ff2dc2dcca69750bfef1e1ebcaccf8c8018175b
Dan: 0x0000357ea5c1a4e7bc11b2b17ff2dc2dcca69750bfef1e1ebcaccf8c8018175b
Dan: 0x357ea5c1a4e7bc11b2b17ff2dc2dcca69750bfef1e1ebcaccf8c8018175b
创建账户
当用户请求创建帐户时,例如使用 Aptos SDK,将执行以下加密步骤 :
- 首先生成一个新的私钥,公钥对。
- 从用户那里获得帐户的首选签名方案:单账户或者多重签名账户。
- 将公钥与用户的签名方案相结合,生成一个 32 字节的认证密钥。
- 将账号序号初始化为 0。认证密钥和序号都作为初始账号资源存储在账号中。
- 从初始身份验证密钥创建 32 字节的帐户地址。
从现在开始,用户应该使用私钥来签署与此帐户的交易。
账户序列号
一个账户的序列号表示从该账户在链上提交和提交的交易数量。每次从该帐户发送的交易被执行或中止并存储在区块链中时,它都会增加。
提交的每笔交易都必须包含发件人帐户的当前序列号。当 Aptos 区块链处理交易时,它会查看交易中的序列号,并将其与账户中的序列号(以当前分类帐版本存储在区块链中)进行比较。仅当交易中的序列号与发送方帐户的序列号相同时才执行交易,如果不匹配则拒绝。通过这种方式,过去的交易,必然包含较旧的序列号,不能被重放,从而防止重放攻击。
这些交易将保存在内存池中,直到它们成为该帐户的下一个序列号(或直到它们过期)。申请交易时,账户的序号会加 1。账户有严格递增的序号。
账户地址
在新帐户创建过程中,首先存在一个 32 字节的身份验证密钥。 然后,此身份验证密钥按原样作为 32 字节帐户地址返回。
但是,身份验证密钥可能随后会发生变化,例如,当您生成一对新的私钥(公钥)以轮换密钥时。 但账户地址不会改变。 因此,仅最初 32 字节的身份验证密钥将与 32 字节的帐户地址相同。 创建帐户后,即使私钥、公钥和认证密钥可能发生变化,帐户地址也将保持不变。 现有帐户的地址无法更改。
签名方案
一个帐户可以发送交易。 Aptos 区块链支持以下签名方案:
- 单签名交易的Ed25519,以及
- MultiEd25519,用于多重签名交易。
Aptos 区块链默认为单签名交易。
签名方案标识符
为帐户生成身份验证密钥需要您为此帐户提供以下 1 字节签名方案标识符之一,即该帐户是单签名帐户还是多重签名帐户:
- 1 字节单签名方案标识符:
0x00
。 - 1 字节多重签名方案标识符:
0x01
。 确保还提供K
的值以生成 K-of-N 多重签名身份验证密钥。
单签名者身份验证
为单个签名账户生成认证密钥和账户地址:
- 生成密钥对:生成新的密钥对(
privkey_A
、pubkey_A
)。 Aptos 区块链在 Ed25519 曲线上使用 PureEdDSA 方案,如 RFC 8032 中所定义。 - 导出一个 32 字节的身份验证密钥:从
pubkey_A
导出一个 32 字节的身份验证密钥:其中auth_key = sha3-256(pubkey_A | 0x00)
|
表示连接。0x00
是 1 字节的单签名方案标识符。 - 使用这个初始认证密钥作为永久账户地址。
多重签名者身份验证
使用 K-of-N 多重签名身份验证时,帐户总共有 N 个签名者,并且必须使用这 N 个签名中的至少 K 个来对交易进行身份验证。
要生成 K-of-N 多重签名帐户的身份验证密钥和帐户地址:
- 生成密钥对:生成
N
ed25519 公钥p_1
, ...,p_n
。 - 确定
K
的值,即验证交易所需的签名阈值数量。 - 导出一个 32 字节的认证密钥:计算认证密钥,如下所述:
auth_key = sha3-256(p_1 | . . . | p_n | K | 0x01)
0x01
是 1 字节的多重签名方案标识符。 - 使用这个初始认证密钥作为永久账户地址。
为了创建账户,Aptos 测试网需要将账户的公钥和一定数量的 Coin<TestCoin>
添加到该账户,从而使用这两种资源创建一个新账户。
带有签名者的访问控制
交易的发送者由签名者发送。 当 Move 模块中的函数将singer
作为参数时,Aptos Move VM 会将签署交易的帐户的身份转换为 Move 模块入口点中的签名者。 请参阅下面的initialize
和withdraw
函数中带有signer
的 Move 示例代码。 当函数中未指定singer
时,例如,下面的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 区块链分布式数据库中发布的模块中声明的类型。