Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Self::zero and self::is_zero() for 13 types #5973

Merged
merged 23 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/book/src/blockchain-development/access_control.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The `msg_sender` function works as follows:

Many contracts require some form of ownership for access control. The [SRC-5 Ownership Standard](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-5.md) has been defined to provide an interoperable interface for ownership within contracts.

To accomplish this, use the [Ownership Library](https://fuellabs.github.io/sway-libs/book/ownership/index.html) to keep track of the owner. This allows setting and revoking ownership using the variants `Some(..)` and `None` respectively. This is better, safer, and more readable than using the `Identity` type directly where revoking ownership has to be done using some magic value such as `std::constants::ZERO_B256` or otherwise.
To accomplish this, use the [Ownership Library](https://fuellabs.github.io/sway-libs/book/ownership/index.html) to keep track of the owner. This allows setting and revoking ownership using the variants `Some(..)` and `None` respectively. This is better, safer, and more readable than using the `Identity` type directly where revoking ownership has to be done using some magic value such as `b256::zero()` or otherwise.

- The following is an example of how to properly lock a function such that only the owner may call a function:

Expand Down
2 changes: 1 addition & 1 deletion docs/book/src/blockchain-development/native_assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ In the case where the `b256` value of an asset is already known, you may call th

The SubId is used to differentiate between different assets that are created by the same contract. The `SubId` is a `b256` value.

When creating an single new asset on Fuel, we recommend using the `DEFAULT_ASSET_ID`.
When creating a single new asset on Fuel, we recommend using the `DEFAULT_SUB_ID` or `SubId::zero()`.

## The Base Asset

Expand Down
2 changes: 1 addition & 1 deletion docs/book/src/sway-program-types/smart_contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@ Each special parameter is optional and assumes a default value when skipped:

1. The default value for `gas` is the context gas (i.e. the content of the special register `$cgas`). Refer to the [FuelVM specifications](https://fuellabs.github.io/fuel-specs/master/vm) for more information about context gas.
2. The default value for `coins` is 0.
3. The default value for `asset_id` is `ZERO_B256`.
3. The default value for `asset_id` is `b256::zero()`.
14 changes: 6 additions & 8 deletions docs/reference/src/code/operations/asset_operations/src/lib.sw
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ use std::asset::burn;
use std::asset::transfer;
// ANCHOR_END: transfer_import

use std::constants::ZERO_B256;

fn minting() {
// ANCHOR: mint
let amount = 10;
mint(ZERO_B256, amount);
mint(SubId::zero(), amount);
// ANCHOR_END: mint
}

Expand All @@ -28,7 +26,7 @@ fn minting_to_address() {
let address = 0x0000000000000000000000000000000000000000000000000000000000000001;
let user = Address::from(address);

mint_to(Identity::Address(user), ZERO_B256, amount);
mint_to(Identity::Address(user), SubId::zero(), amount);
// ANCHOR_END: mint_to_address
}

Expand All @@ -38,7 +36,7 @@ fn minting_to_contract() {
let address = 0x0000000000000000000000000000000000000000000000000000000000000001;
let pool = ContractId::from(address);

mint_to(Identity::ContractId(pool), ZERO_B256, amount);
mint_to(Identity::ContractId(pool), SubId::zero(), amount);
// ANCHOR_END: mint_to_contract
}

Expand All @@ -49,15 +47,15 @@ fn minting_to() {
let user = Identity::Address(Address::from(address));
let pool = Identity::ContractId(ContractId::from(address));

mint_to(user, ZERO_B256, amount);
mint_to(pool, ZERO_B256, amount);
mint_to(user, SubId::zero(), amount);
mint_to(pool, SubId::zero(), amount);
// ANCHOR_END: mint_to
}

fn burning() {
// ANCHOR: burn
let amount = 10;
burn(ZERO_B256, amount);
burn(SubId::zero(), amount);
// ANCHOR_END: burn
}

Expand Down
7 changes: 3 additions & 4 deletions examples/advanced_storage_variables/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ contract;

use std::{
bytes::Bytes,
constants::ZERO_B256,
hash::Hash,
storage::{
storage_bytes::*,
Expand Down Expand Up @@ -81,19 +80,19 @@ impl StorageExample for Contract {
.push(0x0000000000000000000000000000000000000000000000000000000000000002);

// Set will overwrite the element stored at the given index.
storage.storage_vec.set(2, ZERO_B256);
storage.storage_vec.set(2, b256::zero());
// ANCHOR_END: vec_storage_write
}
#[storage(read, write)]
fn get_vec() {
// ANCHOR: vec_storage_read
// Method 1: Access the element directly
// Note: get() does not remove the element from the vec.
let stored_val1: b256 = storage.storage_vec.get(0).unwrap().try_read().unwrap_or(ZERO_B256);
let stored_val1: b256 = storage.storage_vec.get(0).unwrap().try_read().unwrap_or(b256::zero());

// Method 2: First get the storage key and then access the value.
let storage_key2: StorageKey<b256> = storage.storage_vec.get(1).unwrap();
let stored_val2: b256 = storage_key2.try_read().unwrap_or(ZERO_B256);
let stored_val2: b256 = storage_key2.try_read().unwrap_or(b256::zero());

// pop() will remove the last element from the vec.
let length: u64 = storage.storage_vec.len();
Expand Down
10 changes: 4 additions & 6 deletions examples/basic_storage_variables/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
contract;

use std::constants::ZERO_B256;

// ANCHOR: basic_storage_declaration
storage {
var1: u64 = 1,
var2: b256 = ZERO_B256,
var3: Address = Address::from(ZERO_B256),
var2: b256 = b256::zero(),
var3: Address = Address::zero(),
var4: Option<u8> = None,
}
// ANCHOR_END: basic_storage_declaration
Expand Down Expand Up @@ -37,8 +35,8 @@ impl StorageExample for Contract {
fn get_something() {
// ANCHOR: basic_storage_read
let var1: u64 = storage.var1.read();
let var2: b256 = storage.var2.try_read().unwrap_or(ZERO_B256);
let var3: Address = storage.var3.try_read().unwrap_or(Address::from(ZERO_B256));
let var2: b256 = storage.var2.try_read().unwrap_or(b256::zero());
let var3: Address = storage.var3.try_read().unwrap_or(Address::zero());
let var4: Option<u8> = storage.var4.try_read().unwrap_or(None);
// ANCHOR_END: basic_storage_read
}
Expand Down
4 changes: 2 additions & 2 deletions examples/identity/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ mod errors;
use abi::IdentityExample;
use errors::MyError;

use std::{asset::transfer, constants::{ZERO_B256,},};
use std::asset::transfer;

storage {
owner: Identity = Identity::ContractId(ContractId::from(ZERO_B256)),
owner: Identity = Identity::ContractId(ContractId::zero()),
}

impl IdentityExample for Contract {
Expand Down
1 change: 0 additions & 1 deletion examples/nested_storage_variables/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ contract;

use std::{
bytes::Bytes,
constants::ZERO_B256,
hash::{
Hash,
sha256,
Expand Down
4 changes: 1 addition & 3 deletions examples/ownership/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
contract;

use std::constants::ZERO_B256;

// SRC-5 Ownership Standard `State` enum
pub enum State {
Uninitialized: (),
Expand Down Expand Up @@ -46,7 +44,7 @@ abi OwnershipExample {

// ANCHOR: set_owner_example_storage
storage {
owner: Ownership = Ownership::initialized(Identity::Address(Address::from(ZERO_B256))),
owner: Ownership = Ownership::initialized(Identity::Address(Address::zero())),
}
// ANCHOR_END: set_owner_example_storage

Expand Down
3 changes: 1 addition & 2 deletions examples/wallet_contract_caller_script/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
script;

use std::constants::ZERO_B256;
use wallet_abi::Wallet;

fn main() {
Expand All @@ -12,6 +11,6 @@ fn main() {
.send_funds {
gas: 10000,
coins: 0,
asset_id: ZERO_B256,
asset_id: b256::zero(),
}(amount_to_send, recipient_address);
}
112 changes: 109 additions & 3 deletions sway-lib-core/src/primitives.sw
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,24 @@ impl u256 {
pub fn bits() -> u64 {
256
}

/// Returns the zero value for the `u256` type.
///
/// # Returns
///
/// * [u256] -> The zero value for the `u256` type.
///
/// # Examples
///
/// ```sway
/// fn foo() {
/// let zero_u256 = u256::zero();
/// assert(zero_u256 == 0x00u256);
/// }
/// ```
pub fn zero() -> Self {
0x00u256
}
}

impl u64 {
Expand Down Expand Up @@ -112,6 +130,24 @@ impl u64 {
pub fn bits() -> u64 {
64
}

/// Returns the zero value for the `u64` type.
///
/// # Returns
///
/// * [u64] -> The zero value for the `u64` type.
///
/// # Examples
///
/// ```sway
/// fn foo() {
/// let zero_u64 = u64::zero();
/// assert(zero_u64 == 0u64);
/// }
/// ```
pub fn zero() -> Self {
0u64
}
}

impl u32 {
Expand Down Expand Up @@ -169,6 +205,24 @@ impl u32 {
pub fn bits() -> u64 {
32
}

/// Returns the zero value for the `u32` type.
///
/// # Returns
///
/// * [u32] -> The zero value for the `u32` type.
///
/// # Examples
///
/// ```sway
/// fn foo() {
/// let zero_u32 = u32::zero();
/// assert(zero_u32 == 0u32);
/// }
/// ```
pub fn zero() -> Self {
0u32
}
}

impl u16 {
Expand Down Expand Up @@ -226,6 +280,24 @@ impl u16 {
pub fn bits() -> u64 {
16
}

/// Returns the zero value for the `u16` type.
///
/// # Returns
///
/// * [u16] -> The zero value for the `u16` type.
///
/// # Examples
///
/// ```sway
/// fn foo() {
/// let zero_u16 = u16::zero();
/// assert(zero_u16 == 0u16);
/// }
/// ```
pub fn zero() -> Self {
0u16
}
}

impl u8 {
Expand Down Expand Up @@ -283,6 +355,24 @@ impl u8 {
pub fn bits() -> u64 {
8
}

// Returns the zero value for the `u8` type.
///
/// # Returns
///
/// * [u8] -> The zero value for the `u8` type.
///
/// # Examples
///
/// ```sway
/// fn foo() {
/// let zero_u8 = u8::zero();
/// assert(zero_u8 == 0u8);
/// }
/// ```
pub fn zero() -> Self {
0u8
}
}

impl b256 {
Expand All @@ -295,11 +385,9 @@ impl b256 {
/// # Examples
///
/// ```sway
/// use std::constants::ZERO_B256;
///
/// fn foo() {
/// let val = b256::min();
/// assert(val == ZERO_B256);
/// assert(val == b256::zero());
/// }
/// ```
pub fn min() -> Self {
Expand Down Expand Up @@ -342,4 +430,22 @@ impl b256 {
pub fn bits() -> u64 {
256
}

/// Returns the zero value for the `b256` type.
///
/// # Returns
///
/// * [b256] -> The zero value for the `b256` type.
///
/// # Examples
///
/// ```sway
/// fn foo() {
/// let zero_b256 = b256::zero();
/// assert(zero_b256 == 0x0000000000000000000000000000000000000000000000000000000000000000);
/// }
/// ```
pub fn zero() -> Self {
0x0000000000000000000000000000000000000000000000000000000000000000
}
}