Aptos (Blockchain Platform)

Table of Contents

1. 简介

Aptos 是由 Diem 原团队成员成立的公链项目,它是 Layer 1 区块链,采用 PoS(Proof-of-Stake)共识机制,支持 Move 智能合约。注:另一区块链项目 Sui 也诞生于 Diem 项目,不过 Aptos 和 Sui 区别比较大,节点 RPC 也不同。

1.1. 原生币 APT

Aptos 中的原生币是 APT,最小单位是 octa,它们的关系是 1 APT = 100,000,000 octa;也就是说 APT 有 8 位精度。

2. 帐户

Aptos 地址是 32 字节数据,表示为 hex 字符串时,它是 66 个字符(包含前面两字符 0x),比如:0x9cc107ca00ed1f08c33ebe2ce1d39b213b755e300c608827e0aa7b3d16c6e78f,我们也可以使用 Aptos Name Service 注册一个更好记的帐户名。

Aptos 支持多种认证方式,如表 1 所示。

Table 1: Aptos 认证方式
Authentication Scheme Scheme Identifier Authentication Key Generation
Ed25519 (default) 0x00 auth_key = sha3-256(pubkey_A | 0x00)
MultiEd25519 (legacy) 0x01 auth_key = sha3-256(p_1 | . . . | p_n | K | 0x01)
Secp256k1 ECDSA 0x02 auth_key = sha3-256(0x01 | pubkey | 0x02)
K-of-N multi-signatures 0x03 auth_key = sha3-256(0x02 | 0x01 | pubkey_0 | 0x02 | pubkey_1 | 0x01 | 0x03)

2.1. 地址推导实例

对于默认的 Ed25519 认证,下面 Python 程序演示了 Aptos 和 Sui 的地址推导过程:

import hashlib

pub_key = 'f02b2e4600d68eca9565026b1e9ad528df287a20fe63d98adc5690284e9649d5'  # pub key of ed25519 private key
scheme_identifier = '00'

aptos_addr = hashlib.sha3_256(bytes.fromhex(pub_key + scheme_identifier)).hexdigest()  # aptos: pub_key 在 scheme_identifier 前面,哈希为 sha3_256
print("aptos addr", aptos_addr)  # 9cc107ca00ed1f08c33ebe2ce1d39b213b755e300c608827e0aa7b3d16c6e78f

sui_addr = hashlib.blake2b(bytes.fromhex(scheme_identifier + pub_key), digest_size=32).hexdigest()  # sui: pub_key 在 scheme_identifier 后面,哈希为 blake2b_256
print("sui addr", sui_addr)  # 52a34a4797797d9cb33aa49e383288030936fe34649ec8c1b6e981ed7c1bd1cd

3. 交易

Aptos 中,未签名的交易中包含下面信息:

  1. sender,发送者地址;
  2. sequence_number,发送者 sequence_number(相当于以太坊的 nonce 值);
  3. payload,具体的交易内容。An entry point 和 A script 是两种常见的交易类型,参考:https://aptos.dev/concepts/txns-states#types-of-transaction-payloads
  4. max_gas_amount,最大的 Gas 数量限制;
  5. gas_unit_price,Gas 价格;
  6. expiration_timestamps_secs,交易过期时间;
  7. chain_id;链 Id。主网为 1,测试网为 2。

签名后的交易,提交上链时还要在交易后面附上签名信息。

4. 帐户基本操作(Aptos CLI)

4.1. 安装 Aptos CLI

执行下面命令可以在 Mac 系统中安装 Aptos CLI

$ brew install aptos

4.2. 创建默认帐户,选择默认网络

为了方便后续的操作,我们可以执行 aptos init 进行初始化动作,具体来说它会执行下面操作:

  1. 提示你选择一个默认网络(如 devnet,testnet,mainnet 等),根据你的选择会把对应的 RPC 节点信息保存在文件 $HOME/.aptos/config.yaml 中;
  2. 创建默认帐户,对应的 Ed25519 私钥会保存在文件 $HOME/.aptos/config.yaml 文件中;
  3. 通过 faucet 帮你领取测试币(当然这个步骤当你选择 mainnet 时是不会执行的)。

下面是 aptos init 的执行例子:

$ aptos init                                  # 下面选择了 testnet 作为默认网络
Configuring for profile default
Choose network from [devnet, testnet, mainnet, local, custom | defaults to devnet]
testnet
Enter your private key as a hex literal (0x...) [Current: None | No input: Generate new key (or keep one if present)]

No key given, generating key...
Account 0x9cc107ca00ed1f08c33ebe2ce1d39b213b755e300c608827e0aa7b3d16c6e78f doesn't exist, creating it and funding it with 100000000 Octas
Account 0x9cc107ca00ed1f08c33ebe2ce1d39b213b755e300c608827e0aa7b3d16c6e78f funded successfully

---
Aptos CLI is now set up for account 0x9cc107ca00ed1f08c33ebe2ce1d39b213b755e300c608827e0aa7b3d16c6e78f as profile default!  Run `aptos --help` for more information about commands
{
  "Result": "Success"
}

上面命令成功执行后,我们可以检查一下文件 $HOME/.aptos/config.yaml 的内容:

$ cat ~/.aptos/config.yaml
---
profiles:
  default:
    private_key: "0xb7d58a41ffb3fb0cbfb813624c40fd7c5dad993865e809aec7697c0a02061d11"
    public_key: "0xf02b2e4600d68eca9565026b1e9ad528df287a20fe63d98adc5690284e9649d5"
    account: 9cc107ca00ed1f08c33ebe2ce1d39b213b755e300c608827e0aa7b3d16c6e78f
    rest_url: "https://fullnode.testnet.aptoslabs.com"
    faucet_url: "https://faucet.testnet.aptoslabs.com"

通过上面命令创建的默认帐户为 0x9cc107ca00ed1f08c33ebe2ce1d39b213b755e300c608827e0aa7b3d16c6e78f

4.3. 测试原生币转帐

在测试转账前,我们先创建第 2 个帐户,以作为接收地址:

$ aptos init --profile mysecond         # 这里换个 profile 名称,如 mysecond
$ cat ~/.aptos/config.yaml
---
profiles:
  default:
    private_key: "0xb7d58a41ffb3fb0cbfb813624c40fd7c5dad993865e809aec7697c0a02061d11"
    public_key: "0xf02b2e4600d68eca9565026b1e9ad528df287a20fe63d98adc5690284e9649d5"
    account: 9cc107ca00ed1f08c33ebe2ce1d39b213b755e300c608827e0aa7b3d16c6e78f
    rest_url: "https://fullnode.testnet.aptoslabs.com"
    faucet_url: "https://faucet.testnet.aptoslabs.com"
  mysecond:
    private_key: "0xccfbdef863a7bd27e3a3a7c5a897201b63aa95bfe46f6e44c0d224fc382dbf01"
    public_key: "0xe7e50c939c5889cfce1441acfc066a064d3379d0f4e9f82ed0f6a04a38ec1cc3"
    account: ab156a8328d4b4bdb9ab1fba7d8c28f7d62126d01154a3145e10212b5e7c7bae
    rest_url: "https://fullnode.testnet.aptoslabs.com"
    faucet_url: "https://faucet.testnet.aptoslabs.com"

通过上面命令创建的帐户为 0xab156a8328d4b4bdb9ab1fba7d8c28f7d62126d01154a3145e10212b5e7c7bae

使用 aptos account transfer 可以往另一帐户转帐。下面是从默认帐户地址(即 0x9cc107ca00ed1f08c33ebe2ce1d39b213b755e300c608827e0aa7b3d16c6e78f)往地址 0xab156a8328d4b4bdb9ab1fba7d8c28f7d62126d01154a3145e10212b5e7c7bae 转帐 0.3 APT 的例子:

$ aptos account transfer --account 0xab156a8328d4b4bdb9ab1fba7d8c28f7d62126d01154a3145e10212b5e7c7bae --amount 30000000

命令执行后,创建了交易 0x92d4a42f60e389b22293484a0d51b0e3eb9e9bf8fbf4b97b64deb45615aaad6c

上面交易是通过 module 0x1::aptos_account 中的 transfer 方法实现原生币 APT 的转移的。关于其它的 module 可以参考:https://aptos.dev/reference/move

4.4. 查看余额

通过 RPC /accounts/{address}/resources 可以查看余额,如:

$ curl 'https://fullnode.testnet.aptoslabs.com/v1/accounts/0xab156a8328d4b4bdb9ab1fba7d8c28f7d62126d01154a3145e10212b5e7c7bae/resources'

在命令行中,使用 aptos account list 也可以查看某帐户的余额,如:

$ aptos account list --account 0xab156a8328d4b4bdb9ab1fba7d8c28f7d62126d01154a3145e10212b5e7c7bae      # 查看指定帐户余额
{
  "Result": [
    {
      "0x1::account::Account": {
        "authentication_key": "0xab156a8328d4b4bdb9ab1fba7d8c28f7d62126d01154a3145e10212b5e7c7bae",
        "coin_register_events": {
          "counter": "1",
          "guid": {
            "id": {
              "addr": "0xab156a8328d4b4bdb9ab1fba7d8c28f7d62126d01154a3145e10212b5e7c7bae",
              "creation_num": "0"
            }
          }
        },
        "guid_creation_num": "4",
        "key_rotation_events": {
          "counter": "0",
          "guid": {
            "id": {
              "addr": "0xab156a8328d4b4bdb9ab1fba7d8c28f7d62126d01154a3145e10212b5e7c7bae",
              "creation_num": "1"
            }
          }
        },
        "rotation_capability_offer": {
          "for": {
            "vec": []
          }
        },
        "sequence_number": "0",
        "signer_capability_offer": {
          "for": {
            "vec": []
          }
        }
      }
    },
    {
      "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>": {
        "coin": {
          "value": "130000000"
        },
        "deposit_events": {
          "counter": "2",
          "guid": {
            "id": {
              "addr": "0xab156a8328d4b4bdb9ab1fba7d8c28f7d62126d01154a3145e10212b5e7c7bae",
              "creation_num": "2"
            }
          }
        },
        "frozen": false,
        "withdraw_events": {
          "counter": "0",
          "guid": {
            "id": {
              "addr": "0xab156a8328d4b4bdb9ab1fba7d8c28f7d62126d01154a3145e10212b5e7c7bae",
              "creation_num": "3"
            }
          }
        }
      }
    }
  ]
}

从上面输出中,可知 0xab156a8328d4b4bdb9ab1fba7d8c28f7d62126d01154a3145e10212b5e7c7bae 的原生币余额为 130000000 octa,即 1.3 APT。

5. 智能合约

Aptos 支持 Move 智能合约,这里不介绍它。

5.1. 内置模块

下面是一些内置模块函数及其说明:

0x1::coin::transfer  // 转移代币(原生代币或非原生代币)。当目标帐户不存在时,转移代币会失败!
0x1::aptos_account::transfer  // 转移原生币。当目标帐户不存在时,会先创建目标帐户,并为目标帐户注册原生币相关 MOVE 资源。
0x1::aptos_account::transfer_coins  // 转移代币(原生代币或非原生代币)。当目标帐户不存在时,会先创建目标帐户,并为目标帐户注册代币相关 MOVE 资源。


0x1::aptos_account::create_account  // 创建帐户。


0x1::managed_coin::register  // 它是直接调用的 0x1::coin::register 方法。
0x1::coin::register  // 如果代币相关 MOVE 资源已经在帐户中注册,则退出;否则就调用 0x1::account::register_coin 为帐户注册代币相关 MOVE 资源。
0x1::account::register_coin  // 为帐户注册代币(原生代币或非原生代币)相关 MOVE 资源。
0x1::aptos_account::register_apt  // 为帐户注册原生币相关 MOVE 资源。

关于其它模块函数说明,可参考:https://aptos.dev/en/build/smart-contracts/move-reference

6. 参考

Author: cig01

Created: <2024-04-20 Sat>

Last updated: <2024-04-22 Mon>

Creator: Emacs 27.1 (Org mode 9.4)