account 情報の保存場所を調べてみました

`EOS` の `Account` は結局どこで保存しているかを知りたいので、調べてみました。

## 結論
さきに結論を言いますと

- EOS ネイティブの実装で、`shared_multi_index_container` に下記のマルチインデックステーブルに保持しています
    - account_object 情報
    - account_sequence_object 情報
    - permission 情報

## アカウント作成処理
アカウント作成するとき `newaccount` を実行していますが、
`contracts/eosio.system/eosio.system.cpp#native::newaccount` には、リソースの処理しかありません。
`libraries/chain/eosio_contract.cpp#apply_eosio_newaccount` に実際のアカウント作成を処理しています。
処理の流れとしては、

- 入力データの検証処理
- account_object　データを作成する
- account_sequence_object データを作成する
- permission_object データを作成する（`owner`と`active`２つのレコード）
    - permission_object のshared_authority は構造体であり、認証用の情報を保持している

データ構成は下記になっています。

### account_object

```c++
class account_object : public chainbase::object<account_object_type, account_object> {
  ...
  id_type              id;
  account_name         name;
  uint8_t              vm_type      = 0;
  uint8_t              vm_version   = 0;
  bool                 privileged   = false;

  time_point           last_code_update;
  digest_type          code_version;
  block_timestamp_type creation_date;

  shared_blob    code;
  shared_blob    abi;
  ...

  using account_index = chainbase::shared_multi_index_container<
    account_object,
    indexed_by<
        ordered_unique<tag<by_id>, member<account_object, account_object::id_type, &account_object::id>>,
        ordered_unique<tag<by_name>, member<account_object, account_name, &account_object::name>>
    >
  >;
  ...
}

class account_sequence_object : public chainbase::object<account_sequence_object_type, account_sequence_object>
{
  OBJECT_CTOR(account_sequence_object);

  id_type      id;
  account_name name;
  uint64_t     recv_sequence = 0;
  uint64_t     auth_sequence = 0;
  uint64_t     code_sequence = 0;
  uint64_t     abi_sequence  = 0;
};

struct by_name;
using account_sequence_index = chainbase::shared_multi_index_container<
  account_sequence_object,
  indexed_by<
      ordered_unique<tag<by_id>, member<account_sequence_object, account_sequence_object::id_type, &account_sequence_object::id>>,
      ordered_unique<tag<by_name>, member<account_sequence_object, account_name, &account_sequence_object::name>>
  >
>;
```

### permission_object

```c++
class permission_object : public chainbase::object<permission_object_type, permission_object> {
  ...
  id_type                           id;
  permission_usage_object::id_type  usage_id;
  id_type                           parent; ///< parent permission
  account_name                      owner; ///< the account this permission belongs to
  permission_name                   name; ///< human-readable name for the permission
  time_point                        last_updated; ///< the last time this authority was updated
  shared_authority  
  ...
}

using permission_index = chainbase::shared_multi_index_container<
  permission_object,
  indexed_by<
      ordered_unique<tag<by_id>, member<permission_object, permission_object::id_type, &permission_object::id>>,
      ordered_unique<tag<by_parent>,
        composite_key<permission_object,
            member<permission_object, permission_object::id_type, &permission_object::parent>,
            member<permission_object, permission_object::id_type, &permission_object::id>
        >
      >,
      ordered_unique<tag<by_owner>,
        composite_key<permission_object,
            member<permission_object, account_name, &permission_object::owner>,
            member<permission_object, permission_name, &permission_object::name>
        >
      >,
      ordered_unique<tag<by_name>,
        composite_key<permission_object,
            member<permission_object, permission_name, &permission_object::name>,
            member<permission_object, permission_object::id_type, &permission_object::id>
        >
      >
  >
>;
```

### shared_authority

```c++
struct shared_authority {
  ...

   uint32_t                                   threshold = 0;
   shared_vector<key_weight>                  keys;
   shared_vector<permission_level_weight>     accounts;
   shared_vector<wait_weight>                 waits;
   ...
```

## まとめ
`EOS` アカウント周りは、仕組み的には普通のスマートコントラクトと同じくマルチインデックスを使ってますが、実際の処理とアクセス制限いろいろあるので、ネイティブ実装になっていることを分かりました。