Skip to content

Commit bda45e7

Browse files
committed
add confidential_asset::initialize function
1 parent 12a795f commit bda45e7

5 files changed

Lines changed: 107 additions & 10 deletions

File tree

aptos-move/framework/aptos-framework/doc/confidential_asset.md

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ It enables private transfers by obfuscating token amounts while keeping sender a
2525
- [Struct `ChainAuditorAdminChanged`](#0x1_confidential_asset_ChainAuditorAdminChanged)
2626
- [Constants](#@Constants_0)
2727
- [Function `init_module`](#0x1_confidential_asset_init_module)
28+
- [Function `initialize`](#0x1_confidential_asset_initialize)
2829
- [Function `register`](#0x1_confidential_asset_register)
2930
- [Function `register_and_deposit_and_rollover_pending_balance`](#0x1_confidential_asset_register_and_deposit_and_rollover_pending_balance)
3031
- [Function `deposit_and_rollover_pending_balance`](#0x1_confidential_asset_deposit_and_rollover_pending_balance)
@@ -895,6 +896,16 @@ Chain-auditor admin assigned or rotated by governance.
895896
## Constants
896897

897898

899+
<a id="0x1_confidential_asset_EZERO_AMOUNT"></a>
900+
901+
Deposit or withdrawal amount must be greater than zero.
902+
903+
904+
<pre><code><b>const</b> <a href="confidential_asset.md#0x1_confidential_asset_EZERO_AMOUNT">EZERO_AMOUNT</a>: u64 = 25;
905+
</code></pre>
906+
907+
908+
898909
<a id="0x1_confidential_asset_EINTERNAL_ERROR"></a>
899910

900911
An internal error occurred, indicating unexpected behavior.
@@ -935,6 +946,16 @@ The confidential asset account is already frozen.
935946

936947

937948

949+
<a id="0x1_confidential_asset_EALREADY_INITIALIZED"></a>
950+
951+
The module's <code><a href="confidential_asset.md#0x1_confidential_asset_GlobalConfig">GlobalConfig</a></code> has already been initialized.
952+
953+
954+
<pre><code><b>const</b> <a href="confidential_asset.md#0x1_confidential_asset_EALREADY_INITIALIZED">EALREADY_INITIALIZED</a>: u64 = 27;
955+
</code></pre>
956+
957+
958+
938959
<a id="0x1_confidential_asset_EALREADY_NORMALIZED"></a>
939960

940961
The balance is already normalized and cannot be normalized again.
@@ -1105,6 +1126,16 @@ The range proof system does not support sufficient range.
11051126

11061127

11071128

1129+
<a id="0x1_confidential_asset_ESELF_TRANSFER"></a>
1130+
1131+
The sender and recipient of a confidential transfer must be different accounts.
1132+
1133+
1134+
<pre><code><b>const</b> <a href="confidential_asset.md#0x1_confidential_asset_ESELF_TRANSFER">ESELF_TRANSFER</a>: u64 = 26;
1135+
</code></pre>
1136+
1137+
1138+
11081139
<a id="0x1_confidential_asset_ETOKEN_DISABLED"></a>
11091140

11101141
The token is not allowed for confidential transfers.
@@ -1138,10 +1169,10 @@ supply hooks) are not yet supported in confidential transfers.
11381169

11391170
<a id="0x1_confidential_asset_MAINNET_CHAIN_ID"></a>
11401171

1141-
The mainnet chain ID. If the chain ID is 1, the allow list is enabled.
1172+
The Movement mainnet chain ID. If the chain ID is 126, the allow list is enabled.
11421173

11431174

1144-
<pre><code><b>const</b> <a href="confidential_asset.md#0x1_confidential_asset_MAINNET_CHAIN_ID">MAINNET_CHAIN_ID</a>: u8 = 1;
1175+
<pre><code><b>const</b> <a href="confidential_asset.md#0x1_confidential_asset_MAINNET_CHAIN_ID">MAINNET_CHAIN_ID</a>: u8 = 126;
11451176
</code></pre>
11461177

11471178

@@ -1170,6 +1201,8 @@ The maximum number of transactions can be aggregated on the pending balance befo
11701201

11711202
## Function `init_module`
11721203

1204+
Runs when CA is first published onto an already-live network (governance framework upgrade).
1205+
Does not run at genesis — genesis calls <code>initialize</code> directly (see <code><a href="genesis.md#0x1_genesis_initialize">genesis::initialize</a></code>).
11731206

11741207

11751208
<pre><code><b>fun</b> <a href="confidential_asset.md#0x1_confidential_asset_init_module">init_module</a>(deployer: &<a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>)
@@ -1182,16 +1215,47 @@ The maximum number of transactions can be aggregated on the pending balance befo
11821215

11831216

11841217
<pre><code><b>fun</b> <a href="confidential_asset.md#0x1_confidential_asset_init_module">init_module</a>(deployer: &<a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>) {
1218+
<a href="confidential_asset.md#0x1_confidential_asset_initialize">initialize</a>(deployer)
1219+
}
1220+
</code></pre>
1221+
1222+
1223+
1224+
</details>
1225+
1226+
<a id="0x1_confidential_asset_initialize"></a>
1227+
1228+
## Function `initialize`
1229+
1230+
Publishes the chain-level <code><a href="confidential_asset.md#0x1_confidential_asset_GlobalConfig">GlobalConfig</a></code>. Invoked at genesis via <code><a href="genesis.md#0x1_genesis_initialize">genesis::initialize</a></code>, and on
1231+
a first-time governance publish via <code>init_module</code>. Idempotent: aborts if already initialized.
1232+
1233+
1234+
<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="confidential_asset.md#0x1_confidential_asset_initialize">initialize</a>(aptos_framework: &<a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>)
1235+
</code></pre>
1236+
1237+
1238+
1239+
<details>
1240+
<summary>Implementation</summary>
1241+
1242+
1243+
<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="confidential_asset.md#0x1_confidential_asset_initialize">initialize</a>(aptos_framework: &<a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>) {
1244+
<a href="system_addresses.md#0x1_system_addresses_assert_aptos_framework">system_addresses::assert_aptos_framework</a>(aptos_framework);
1245+
<b>assert</b>!(
1246+
!<b>exists</b>&lt;<a href="confidential_asset.md#0x1_confidential_asset_GlobalConfig">GlobalConfig</a>&gt;(@aptos_framework),
1247+
<a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_already_exists">error::already_exists</a>(<a href="confidential_asset.md#0x1_confidential_asset_EALREADY_INITIALIZED">EALREADY_INITIALIZED</a>)
1248+
);
11851249
<b>assert</b>!(
11861250
bulletproofs::get_max_range_bits() &gt;= <a href="confidential_proof.md#0x1_confidential_proof_get_bulletproofs_num_bits">confidential_proof::get_bulletproofs_num_bits</a>(),
11871251
<a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_internal">error::internal</a>(<a href="confidential_asset.md#0x1_confidential_asset_ERANGE_PROOF_SYSTEM_HAS_INSUFFICIENT_RANGE">ERANGE_PROOF_SYSTEM_HAS_INSUFFICIENT_RANGE</a>)
11881252
);
11891253

1190-
<b>let</b> deployer_address = <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(deployer);
1254+
<b>let</b> deployer_address = <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(aptos_framework);
11911255

11921256
<b>let</b> global_config_ctor_ref = &<a href="object.md#0x1_object_create_object">object::create_object</a>(deployer_address);
11931257

1194-
<b>move_to</b>(deployer, <a href="confidential_asset.md#0x1_confidential_asset_GlobalConfig">GlobalConfig</a> {
1258+
<b>move_to</b>(aptos_framework, <a href="confidential_asset.md#0x1_confidential_asset_GlobalConfig">GlobalConfig</a> {
11951259
allow_list_enabled: <a href="chain_id.md#0x1_chain_id_get">chain_id::get</a>() == <a href="confidential_asset.md#0x1_confidential_asset_MAINNET_CHAIN_ID">MAINNET_CHAIN_ID</a>,
11961260
extend_ref: <a href="object.md#0x1_object_generate_extend_ref">object::generate_extend_ref</a>(global_config_ctor_ref),
11971261
chain_auditor_ek: std::option::none(),
@@ -2486,7 +2550,7 @@ Asset auditor encryption key for <code>token</code>, or <code>None</code> if uns
24862550
{
24872551
<b>let</b> fa_config_address = <a href="confidential_asset.md#0x1_confidential_asset_get_fa_config_address">get_fa_config_address</a>(token);
24882552

2489-
<b>if</b> (!<a href="confidential_asset.md#0x1_confidential_asset_is_allow_list_enabled">is_allow_list_enabled</a>() && !<b>exists</b>&lt;<a href="confidential_asset.md#0x1_confidential_asset_FAConfig">FAConfig</a>&gt;(fa_config_address)) {
2553+
<b>if</b> (!<b>exists</b>&lt;<a href="confidential_asset.md#0x1_confidential_asset_FAConfig">FAConfig</a>&gt;(fa_config_address)) {
24902554
<b>return</b> std::option::none();
24912555
};
24922556

@@ -2708,6 +2772,9 @@ Implementation of the <code>deposit_to</code> entry function.
27082772
<b>assert</b>!(<a href="confidential_asset.md#0x1_confidential_asset_is_safe_for_confidentiality">is_safe_for_confidentiality</a>(&token), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="confidential_asset.md#0x1_confidential_asset_EUNSAFE_DISPATCHABLE_FA">EUNSAFE_DISPATCHABLE_FA</a>));
27092773
<b>assert</b>!(<a href="confidential_asset.md#0x1_confidential_asset_is_token_allowed">is_token_allowed</a>(token), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="confidential_asset.md#0x1_confidential_asset_ETOKEN_DISABLED">ETOKEN_DISABLED</a>));
27102774
<b>assert</b>!(!<a href="confidential_asset.md#0x1_confidential_asset_is_frozen">is_frozen</a>(<b>to</b>, token), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_state">error::invalid_state</a>(<a href="confidential_asset.md#0x1_confidential_asset_EALREADY_FROZEN">EALREADY_FROZEN</a>));
2775+
// A zero deposit moves no funds but still consumes one of the recipient's
2776+
// `<a href="confidential_asset.md#0x1_confidential_asset_MAX_TRANSFERS_BEFORE_ROLLOVER">MAX_TRANSFERS_BEFORE_ROLLOVER</a>` pending slots, letting anyone force rollovers on them.
2777+
<b>assert</b>!(amount &gt; 0, <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="confidential_asset.md#0x1_confidential_asset_EZERO_AMOUNT">EZERO_AMOUNT</a>));
27112778

27122779
<b>let</b> from = <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(sender);
27132780

@@ -2779,6 +2846,9 @@ Withdrawals are always allowed, regardless of the token allow status.
27792846
proof: WithdrawalProof) <b>acquires</b> <a href="confidential_asset.md#0x1_confidential_asset_ConfidentialAssetStore">ConfidentialAssetStore</a>, <a href="confidential_asset.md#0x1_confidential_asset_GlobalConfig">GlobalConfig</a>
27802847
{
27812848
<b>assert</b>!(<a href="confidential_asset.md#0x1_confidential_asset_is_safe_for_confidentiality">is_safe_for_confidentiality</a>(&token), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="confidential_asset.md#0x1_confidential_asset_EUNSAFE_DISPATCHABLE_FA">EUNSAFE_DISPATCHABLE_FA</a>));
2849+
// A zero withdrawal would re-randomize the actual balance and mark it normalized,
2850+
// acting <b>as</b> a `normalize` that skips the `<a href="confidential_asset.md#0x1_confidential_asset_EALREADY_NORMALIZED">EALREADY_NORMALIZED</a>` guard.
2851+
<b>assert</b>!(amount &gt; 0, <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="confidential_asset.md#0x1_confidential_asset_EZERO_AMOUNT">EZERO_AMOUNT</a>));
27822852

27832853
<b>let</b> from = <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(sender);
27842854

@@ -2855,6 +2925,7 @@ Implementation of the <code>confidential_transfer</code> entry function.
28552925
proof: TransferProof,
28562926
sender_auditor_hint: <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;) <b>acquires</b> <a href="confidential_asset.md#0x1_confidential_asset_ConfidentialAssetStore">ConfidentialAssetStore</a>, <a href="confidential_asset.md#0x1_confidential_asset_FAConfig">FAConfig</a>, <a href="confidential_asset.md#0x1_confidential_asset_GlobalConfig">GlobalConfig</a>
28572927
{
2928+
<b>assert</b>!(<a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(sender) != <b>to</b>, <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="confidential_asset.md#0x1_confidential_asset_ESELF_TRANSFER">ESELF_TRANSFER</a>));
28582929
<b>assert</b>!(<a href="confidential_asset.md#0x1_confidential_asset_is_safe_for_confidentiality">is_safe_for_confidentiality</a>(&token), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="confidential_asset.md#0x1_confidential_asset_EUNSAFE_DISPATCHABLE_FA">EUNSAFE_DISPATCHABLE_FA</a>));
28592930
<b>assert</b>!(<a href="confidential_asset.md#0x1_confidential_asset_is_token_allowed">is_token_allowed</a>(token), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="confidential_asset.md#0x1_confidential_asset_ETOKEN_DISABLED">ETOKEN_DISABLED</a>));
28602931
<b>assert</b>!(!<a href="confidential_asset.md#0x1_confidential_asset_is_frozen">is_frozen</a>(<b>to</b>, token), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_state">error::invalid_state</a>(<a href="confidential_asset.md#0x1_confidential_asset_EALREADY_FROZEN">EALREADY_FROZEN</a>));

aptos-move/framework/aptos-framework/doc/confidential_proof.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ Represents the proof structure for validating a key rotation operation.
985985

986986

987987

988-
<pre><code><b>const</b> <a href="confidential_proof.md#0x1_confidential_proof_BULLETPROOFS_DST">BULLETPROOFS_DST</a>: <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt; = [65, 112, 116, 111, 115, 67, 111, 110, 102, 105, 100, 101, 110, 116, 105, 97, 108, 65, 115, 115, 101, 116, 47, 66, 117, 108, 108, 101, 116, 112, 114, 111, 111, 102, 82, 97, 110, 103, 101, 80, 114, 111, 111, 102];
988+
<pre><code><b>const</b> <a href="confidential_proof.md#0x1_confidential_proof_BULLETPROOFS_DST">BULLETPROOFS_DST</a>: <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt; = [77, 111, 118, 101, 109, 101, 110, 116, 67, 111, 110, 102, 105, 100, 101, 110, 116, 105, 97, 108, 65, 115, 115, 101, 116, 47, 66, 117, 108, 108, 101, 116, 112, 114, 111, 111, 102, 82, 97, 110, 103, 101, 80, 114, 111, 111, 102];
989989
</code></pre>
990990

991991

aptos-move/framework/aptos-framework/doc/genesis.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<b>use</b> <a href="chain_id.md#0x1_chain_id">0x1::chain_id</a>;
4343
<b>use</b> <a href="chain_status.md#0x1_chain_status">0x1::chain_status</a>;
4444
<b>use</b> <a href="coin.md#0x1_coin">0x1::coin</a>;
45+
<b>use</b> <a href="confidential_asset.md#0x1_confidential_asset">0x1::confidential_asset</a>;
4546
<b>use</b> <a href="consensus_config.md#0x1_consensus_config">0x1::consensus_config</a>;
4647
<b>use</b> <a href="create_signer.md#0x1_create_signer">0x1::create_signer</a>;
4748
<b>use</b> <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error">0x1::error</a>;
@@ -364,6 +365,9 @@ Genesis step 1: Initialize aptos framework account and core modules on chain.
364365
<a href="block.md#0x1_block_initialize">block::initialize</a>(&aptos_framework_account, epoch_interval_microsecs);
365366
<a href="state_storage.md#0x1_state_storage_initialize">state_storage::initialize</a>(&aptos_framework_account);
366367
<a href="nonce_validation.md#0x1_nonce_validation_initialize">nonce_validation::initialize</a>(&aptos_framework_account);
368+
// Confidential asset ships in the <a href="genesis.md#0x1_genesis">genesis</a> framework bundle, so its `init_module` never runs;
369+
// publish its `GlobalConfig` explicitly. Must follow `<a href="chain_id.md#0x1_chain_id_initialize">chain_id::initialize</a>` (read above).
370+
<a href="confidential_asset.md#0x1_confidential_asset_initialize">confidential_asset::initialize</a>(&aptos_framework_account);
367371
}
368372
</code></pre>
369373

aptos-move/framework/aptos-framework/sources/confidential_asset/confidential_asset.move

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ module aptos_framework::confidential_asset {
2727
#[test_only]
2828
use aptos_std::ristretto255::Scalar;
2929

30+
friend aptos_framework::genesis;
31+
3032
//
3133
// Errors
3234
//
@@ -110,6 +112,9 @@ module aptos_framework::confidential_asset {
110112
/// The sender and recipient of a confidential transfer must be different accounts.
111113
const ESELF_TRANSFER: u64 = 26;
112114

115+
/// The module's `GlobalConfig` has already been initialized.
116+
const EALREADY_INITIALIZED: u64 = 27;
117+
113118
//
114119
// Constants
115120
//
@@ -356,20 +361,33 @@ module aptos_framework::confidential_asset {
356361
}
357362

358363
//
359-
// Module initialization, done only once when this module is first published on the blockchain
364+
// Module initialization
360365
//
361366

367+
/// Runs when CA is first published onto an already-live network (governance framework upgrade).
368+
/// Does not run at genesis — genesis calls `initialize` directly (see `genesis::initialize`).
362369
fun init_module(deployer: &signer) {
370+
initialize(deployer)
371+
}
372+
373+
/// Publishes the chain-level `GlobalConfig`. Invoked at genesis via `genesis::initialize`, and on
374+
/// a first-time governance publish via `init_module`. Idempotent: aborts if already initialized.
375+
public(friend) fun initialize(aptos_framework: &signer) {
376+
system_addresses::assert_aptos_framework(aptos_framework);
377+
assert!(
378+
!exists<GlobalConfig>(@aptos_framework),
379+
error::already_exists(EALREADY_INITIALIZED)
380+
);
363381
assert!(
364382
bulletproofs::get_max_range_bits() >= confidential_proof::get_bulletproofs_num_bits(),
365383
error::internal(ERANGE_PROOF_SYSTEM_HAS_INSUFFICIENT_RANGE)
366384
);
367385

368-
let deployer_address = signer::address_of(deployer);
386+
let deployer_address = signer::address_of(aptos_framework);
369387

370388
let global_config_ctor_ref = &object::create_object(deployer_address);
371389

372-
move_to(deployer, GlobalConfig {
390+
move_to(aptos_framework, GlobalConfig {
373391
allow_list_enabled: chain_id::get() == MAINNET_CHAIN_ID,
374392
extend_ref: object::generate_extend_ref(global_config_ctor_ref),
375393
chain_auditor_ek: std::option::none(),
@@ -1662,7 +1680,7 @@ module aptos_framework::confidential_asset {
16621680

16631681
#[test_only]
16641682
public fun init_module_for_testing(deployer: &signer) {
1665-
init_module(deployer)
1683+
initialize(deployer)
16661684
}
16671685

16681686
#[test_only]

aptos-move/framework/aptos-framework/sources/genesis.move

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module aptos_framework::genesis {
1313
use aptos_framework::block;
1414
use aptos_framework::chain_id;
1515
use aptos_framework::chain_status;
16+
use aptos_framework::confidential_asset;
1617
use aptos_framework::coin;
1718
use aptos_framework::consensus_config;
1819
use aptos_framework::execution_config;
@@ -132,6 +133,9 @@ module aptos_framework::genesis {
132133
block::initialize(&aptos_framework_account, epoch_interval_microsecs);
133134
state_storage::initialize(&aptos_framework_account);
134135
nonce_validation::initialize(&aptos_framework_account);
136+
// Confidential asset ships in the genesis framework bundle, so its `init_module` never runs;
137+
// publish its `GlobalConfig` explicitly. Must follow `chain_id::initialize` (read above).
138+
confidential_asset::initialize(&aptos_framework_account);
135139
}
136140

137141
/// Genesis step 2: Initialize Aptos coin.

0 commit comments

Comments
 (0)