From 37b0a7069f3f08676355fc2678a62780c1a383c4 Mon Sep 17 00:00:00 2001 From: Cameron Carstens <54727135+bitzoic@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:22:29 +0300 Subject: [PATCH] Introduce the `DEFAULT_SUB_ID` constant (#5246) ## Description The following pull request does two things: 1. Introduces the `DEFAULT_SUB_ID` constant. This is equivalent to the `ZERO_B256` constant. This constant makes the Sway code easier to read and comprehend improving the developer's UX. The actual value of the default is something the developer no longer needs to think about. Before: ```sway let my_asset = AssetId::new(my_contract, ZERO_B256); ``` Now: ```sway let my_asset = AssetId::new(my_contract, DEFAULT_SUB_ID); ``` 2. Removes the `ContractId` argument from the `AssetId::default()` function. In 90% of cases `default()` is used within the contract that issued the token, making this an unnecessary argument. This function now fetches the contract id of the contract it's called in, thus eliminating the need to import another function and add additional arguments. In the case a developer needs the default of another contract, the `DEFAULT_SUB_ID` can be used instead making the distinction more legible and apparent. Before: ```sway use std::call_frames::contract_id; fn foo(other_contract: ContractId) { let other_asset = AssetId::default(other_contract); let my_asset = AssetId::default(contract_id()); } ``` After: ```sway fn foo(other_contract: ContractId) { let other_asset = AssetId::new(other_contract, DEFAULT_SUB_ID); let my_asset = AssetId::default(); } ``` ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: SwayStar123 <46050679+SwayStar123@users.noreply.github.com> --- examples/liquidity_pool/src/main.sw | 6 +++--- examples/native_token/src/main.sw | 10 ++++----- sway-lib-std/src/constants.sw | 14 +++++++++++++ sway-lib-std/src/contract_id.sw | 21 +++++++------------ .../token_ops_test/src/main.sw | 3 ++- .../context_caller_contract/src/main.sw | 14 ++++++------- 6 files changed, 38 insertions(+), 30 deletions(-) diff --git a/examples/liquidity_pool/src/main.sw b/examples/liquidity_pool/src/main.sw index 112b9356eda..f851cdc040e 100644 --- a/examples/liquidity_pool/src/main.sw +++ b/examples/liquidity_pool/src/main.sw @@ -5,7 +5,7 @@ use std::{ contract_id, msg_asset_id, }, - constants::ZERO_B256, + constants::DEFAULT_SUB_ID, context::msg_amount, hash::*, token::{ @@ -32,11 +32,11 @@ impl LiquidityPool for Contract { let amount_to_mint = msg_amount() * 2; // Mint some LP token based upon the amount of the base token. - mint_to_address(recipient, ZERO_B256, amount_to_mint); + mint_to_address(recipient, DEFAULT_SUB_ID, amount_to_mint); } fn withdraw(recipient: Address) { - let asset_id = AssetId::default(contract_id()); + let asset_id = AssetId::default(); assert(msg_asset_id() == asset_id); assert(msg_amount() > 0); diff --git a/examples/native_token/src/main.sw b/examples/native_token/src/main.sw index efcdd948f50..5de3ce1625e 100644 --- a/examples/native_token/src/main.sw +++ b/examples/native_token/src/main.sw @@ -1,6 +1,6 @@ contract; -use std::{constants::ZERO_B256, context::*, token::*}; +use std::{constants::DEFAULT_SUB_ID, context::*, token::*}; abi NativeAssetToken { fn mint_coins(mint_amount: u64); @@ -16,12 +16,12 @@ abi NativeAssetToken { impl NativeAssetToken for Contract { /// Mint an amount of this contracts native asset to the contracts balance. fn mint_coins(mint_amount: u64) { - mint(ZERO_B256, mint_amount); + mint(DEFAULT_SUB_ID, mint_amount); } /// Burn an amount of this contracts native asset. fn burn_coins(burn_amount: u64) { - burn(ZERO_B256, burn_amount); + burn(DEFAULT_SUB_ID, burn_amount); } /// Transfer coins to a target contract. @@ -46,11 +46,11 @@ impl NativeAssetToken for Contract { /// Mint and send this contracts native token to a destination contract. fn mint_and_send_to_contract(amount: u64, destination: ContractId) { - mint_to_contract(destination, ZERO_B256, amount); + mint_to_contract(destination, DEFAULT_SUB_ID, amount); } /// Mind and send this contracts native token to a destination address. fn mint_and_send_to_address(amount: u64, recipient: Address) { - mint_to_address(recipient, ZERO_B256, amount); + mint_to_address(recipient, DEFAULT_SUB_ID, amount); } } diff --git a/sway-lib-std/src/constants.sw b/sway-lib-std/src/constants.sw index 2bbcc85047e..17fdaa604b9 100644 --- a/sway-lib-std/src/constants.sw +++ b/sway-lib-std/src/constants.sw @@ -32,3 +32,17 @@ pub const BASE_ASSET_ID: AssetId = AssetId::from(ZERO_B256); /// } /// ``` pub const ZERO_B256 = 0x0000000000000000000000000000000000000000000000000000000000000000; + +/// The default Sub Id for assets. +/// +/// # Examples +/// +/// ```sway +/// use std::{call_frames::contract_id, constants::DEFAULT_SUB_ID}; +/// +/// fn foo() { +/// let asset = AssetId::default(); +/// assert(AssetId::new(contract_id(), DEFAULT_SUB_ID) == msg_asset_id()); +/// } +/// ``` +pub const DEFAULT_SUB_ID = ZERO_B256; diff --git a/sway-lib-std/src/contract_id.sw b/sway-lib-std/src/contract_id.sw index 7b7b65d8be1..4ec7d8cafc9 100644 --- a/sway-lib-std/src/contract_id.sw +++ b/sway-lib-std/src/contract_id.sw @@ -178,31 +178,24 @@ impl AssetId { Self { value: result_buffer } } - /// Creates a new AssetId from a ContractId and the zero SubId. - /// - /// # Arguments - /// - /// * `contract_id`: [ContractId] - The ContractId of the contract that created the asset. + /// Creates a new AssetId with the default SubId for the current contract. /// /// # Returns /// - /// * [AssetId] - The AssetId of the asset. Computed by hashing the ContractId and the zero SubId. + /// * [AssetId] - The AssetId of the asset. Computed by hashing the ContractId and the default SubId. /// /// # Examples /// /// ```sway - /// use std::{callframes::contract_id, constants::ZERO_B256}; + /// use std::{callframes::contract_id, constants::DEFAULT_SUB_ID}; /// /// fn foo() { - /// let contract_id = contract_id(); - /// let sub_id = ZERO_B256; - /// - /// let asset_id = AssetId::default(contract_id); - /// - /// assert(asset_id == AssetId::new(contract_id, sub_id)); + /// let asset_id = AssetId::default(); + /// assert(asset_id == AssetId::new(contract_id(), DEFAULT_SUB_ID)); /// } /// ``` - pub fn default(contract_id: ContractId) -> Self { + pub fn default() -> Self { + let contract_id = asm() { fp: b256 }; let result_buffer = 0x0000000000000000000000000000000000000000000000000000000000000000; asm(asset_id: result_buffer, ptr: (contract_id, 0x0000000000000000000000000000000000000000000000000000000000000000), bytes: 64) { s256 asset_id ptr bytes; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/token_ops_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/token_ops_test/src/main.sw index f5a63eea46d..22a81265ee2 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/token_ops_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/token_ops_test/src/main.sw @@ -3,6 +3,7 @@ script; use std::context::balance_of; use std::token::*; use std::contract_id::*; +use std::constants::DEFAULT_SUB_ID; use test_fuel_coin_abi::*; struct Opts { @@ -16,7 +17,7 @@ fn main() -> bool { // the deployed fuel_coin Contract_Id: let fuelcoin_id = ContractId::from(0x5d10689c7eecb405937a3f35fab7baf05a3f6189f9a2993ee70e21ccc1212460); - let fuelcoin_asset_id = AssetId::default(fuelcoin_id); + let fuelcoin_asset_id = AssetId::new(fuelcoin_id, DEFAULT_SUB_ID); // contract ID for sway/test/src/e2e_vm_tests/test_programs/should_pass/test_contracts/balance_test_contract/ let balance_test_id = ContractId::from(0x4a00baa517980432b9274a0e2f03c88735bdb483730816679c6eb37b4046d060); diff --git a/test/src/sdk-harness/test_artifacts/context_caller_contract/src/main.sw b/test/src/sdk-harness/test_artifacts/context_caller_contract/src/main.sw index 652c7292884..e45eb118c63 100644 --- a/test/src/sdk-harness/test_artifacts/context_caller_contract/src/main.sw +++ b/test/src/sdk-harness/test_artifacts/context_caller_contract/src/main.sw @@ -18,7 +18,7 @@ impl ContextCaller for Contract { fn call_get_this_balance_with_coins(send_amount: u64, target: ContractId) -> u64 { let id = target.value; let context_contract = abi(ContextTesting, id); - let asset_id = AssetId::default(contract_id()); + let asset_id = AssetId::default(); context_contract.get_this_balance { gas: 500_000, @@ -30,7 +30,7 @@ impl ContextCaller for Contract { fn call_get_balance_of_contract_with_coins(send_amount: u64, target: ContractId) -> u64 { let id = target.value; let context_contract = abi(ContextTesting, id); - let asset_id = AssetId::default(contract_id()); + let asset_id = AssetId::default(); context_contract.get_balance_of_contract { gas: 500_000, @@ -42,7 +42,7 @@ impl ContextCaller for Contract { fn call_get_amount_with_coins(send_amount: u64, target: ContractId) -> u64 { let id = target.value; let context_contract = abi(ContextTesting, id); - let asset_id = AssetId::default(contract_id()); + let asset_id = AssetId::default(); context_contract.get_amount { gas: 500_000, @@ -54,7 +54,7 @@ impl ContextCaller for Contract { fn call_get_asset_id_with_coins(send_amount: u64, target: ContractId) -> b256 { let id = target.value; let context_contract = abi(ContextTesting, id); - let asset_id = AssetId::default(contract_id()); + let asset_id = AssetId::default(); context_contract.get_asset_id { gas: 500_000, @@ -66,7 +66,7 @@ impl ContextCaller for Contract { fn call_get_gas_with_coins(send_amount: u64, target: ContractId) -> u64 { let id = target.value; let context_contract = abi(ContextTesting, id); - let asset_id = AssetId::default(contract_id()); + let asset_id = AssetId::default(); context_contract.get_gas { gas: 500_000, @@ -78,7 +78,7 @@ impl ContextCaller for Contract { fn call_get_global_gas_with_coins(send_amount: u64, target: ContractId) -> u64 { let id = target.value; let context_contract = abi(ContextTesting, id); - let asset_id = AssetId::default(contract_id()); + let asset_id = AssetId::default(); context_contract.get_global_gas { gas: 500_000, @@ -90,7 +90,7 @@ impl ContextCaller for Contract { fn call_receive_coins(send_amount: u64, target: ContractId) { let id = target.value; let context_contract = abi(ContextTesting, id); - let asset_id = AssetId::default(contract_id()); + let asset_id = AssetId::default(); context_contract.receive_coins { gas: 500_000,