Skip to content

Commit

Permalink
Merge pull request #963 from multiversx/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
radumojic authored Aug 23, 2024
2 parents 1869d01 + 5258418 commit 806d2fa
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 39 deletions.
77 changes: 40 additions & 37 deletions docs/developers/developer-reference/sc-annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,21 +96,22 @@ Example:
```rust
#[multiversx_sc::contract]
pub trait Example {
#[endpoint]
fn example(&self) {
#[endpoint]
fn example(&self) {
}

#[endpoint(camelCaseEndpointName)]
fn snake_case_method_name(&self, value: BigUint) {
fn snake_case_method_name(&self, value: BigUint) {
}

fn private_method(&self, value: &BigUint) {
}

#[view(getData)]
fn get_data(&self) -> u32{
0
fn get_data(&self) -> u32 {
0
}
}
```

In this example, 3 methods are public endpoints. They are named `example`, `camelCaseEndpointName` and `getData`. All other names are internal and do not show up in the resulting contract.
Expand Down Expand Up @@ -150,12 +151,13 @@ This is the simplest way to retrieve data from the storage. Let's start with an
```rust
#[multiversx_sc::contract]
pub trait Adder {
#[view(getSum)]
#[storage_get("sum")]
fn get_sum(&self) -> BigUint;
#[view(getSum)]
#[storage_get("sum")]
fn get_sum(&self) -> BigUint;

#[storage_get("example_map")]
#[storage_get("example_map")]
fn get_value(&self, key_1: u32, key_2: u32) -> SerializableType;
}
```

First off, please note that a storage method can also be annotated with `#[view]` or `#[endpoint]`. The endpoint annotations refer to the role of the method in the contract, while the storage annotation refers to its implementation, so there is no overlap.
Expand All @@ -179,11 +181,12 @@ This is the simplest way to write data to storage. Example:
```rust
#[multiversx_sc::contract]
pub trait Adder {
#[storage_set("sum")]
fn set_sum(&self, sum: &BigUint);
#[storage_set("sum")]
fn set_sum(&self, sum: &BigUint);

#[storage_set("example_map")]
#[storage_set("example_map")]
fn set_value(&self, key_1: u32, key_2: u32, value: &SerializableType);
}
```

It works very similarly to `storage_get`, with the notable difference that instead of returning a value, the value must be provided as an argument. The value to store is always the last argument.
Expand All @@ -194,14 +197,14 @@ Again, just like for the getter, an arbitrary number of additional map keys can
There is no mechanism in place to ensure that there is no overlap between storage keys. Nothing prevents a developer from writing:

```rust
#[storage_set("sum")]
fn set_sum(&self, sum: &BigUint);
#[storage_set("sum")]
fn set_sum(&self, sum: &BigUint);

#[storage_set("sum")]
fn set_another_sum(&self, another_sum: &BigUint);
#[storage_set("sum")]
fn set_another_sum(&self, another_sum: &BigUint);

#[storage_set("s")]
fn set_value(&self, key: u16, value: &SerializableType);
#[storage_set("s")]
fn set_value(&self, key: u16, value: &SerializableType);
```

The first problem is easy to spot: we have 2 setters with the same key.
Expand All @@ -223,11 +226,11 @@ There are many storage mappers in the framework and more can be custom-defined.
Example:

```rust
#[storage_mapper("user_status")]
fn user_status(&self) -> SingleValueMapper<UserStatus>;
#[storage_mapper("user_status")]
fn user_status(&self) -> SingleValueMapper<UserStatus>;

#[storage_mapper("list_mapper")]
fn list_mapper(&self, sub_key: usize) -> LinkedListMapper<u32>;
#[storage_mapper("list_mapper")]
fn list_mapper(&self, sub_key: usize) -> LinkedListMapper<u32>;
```

The `SingleValueMapper` is the simplest of them all, since it only manages one storage key. Even though it only works with one storage entry, its syntax is more compact than `storage_get`/`storage_set` so it is used quite a lot.
Expand All @@ -243,8 +246,8 @@ Also note that additional sub-keys are also allowed for storage mappers, the sam
This is very similar to `storage_get`, but instead of retrieving the value, it returns a boolean indicating whether the serialized value is empty or not. It does not attempt to deserialize the value, so it can be faster and more resilient than `storage_get`, depending on type.

```rust
#[storage_is_empty("opt_addr")]
fn is_empty_opt_addr(&self) -> bool;
#[storage_is_empty("opt_addr")]
fn is_empty_opt_addr(&self) -> bool;
```

Nowadays, it is more common to use storage mappers. The `SingleValueMapper` has an `is_empty()` method that does the same.
Expand All @@ -257,8 +260,8 @@ This is very similar to `storage_set`, but instead of serializing and writing th
It does not do any serializing, so it can be faster than `storage_set`, depending on type.

```rust
#[storage_clear("field_to_clear")]
fn clear_storage_value(&self);
#[storage_clear("field_to_clear")]
fn clear_storage_value(&self);
```

Nowadays, it is more common to use storage mappers. The `SingleValueMapper` has an `clear()` method that does the same.
Expand All @@ -274,14 +277,14 @@ Because they are not saved on the chain in full, they are also a lot cheaper tha
In smart contracts we define them as trait methods with no implementation, as follows:

```rust
#[event("transfer")]
fn transfer_event(
&self,
#[indexed] from: &ManagedAddress,
#[indexed] to: &ManagedAddress,
#[indexed] token_id: u32,
data: ManagedBuffer,
);
#[event("transfer")]
fn transfer_event(
&self,
#[indexed] from: &ManagedAddress,
#[indexed] to: &ManagedAddress,
#[indexed] token_id: u32,
data: ManagedBuffer,
);
```

The annotation always requires the name of the event to be specified explicitly in brackets.
Expand All @@ -308,8 +311,8 @@ This is a simple getter, which provides a convenient instance of a contract prox
```rust
#[multiversx_sc::module]
pub trait ForwarderAsyncCallModule {
#[proxy]
fn vault_proxy(&self, to: Address) -> vault::Proxy<Self::Api>;
#[proxy]
fn vault_proxy(&self, to: Address) -> vault::Proxy<Self::Api>;

// ...
}
Expand Down
2 changes: 1 addition & 1 deletion docs/developers/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Learn about transaction's gas and how a fee is calculated:
| Name | Description |
|----------------------------------------------------------------------|----------------------------------------------------------|
| [Overview](/developers/testing/rust/sc-test-overview) | Introduction to all the testing methods available in Rust|
| [Blackbox tests](/developers/testing/rust/sc-blackbox-calls) | The best way to write integration tests, by simulating transactionds|
| [Blackbox tests](/developers/testing/rust/sc-blackbox-calls) | The best way to write integration tests, by simulating transactions|
| [Whitebox framework](/developers/testing/rust/whitebox-legacy) | Older testing framework, but still in use in some projects.|
| [Whitebox framework functions reference](/developers/testing/rust/whitebox-legacy-functions-reference) | A list of available functions to be used when using the whitebox framework. |
| [Debugging](/developers/testing/sc-debugging) | How to debug your smart contract tests. |
Expand Down
2 changes: 1 addition & 1 deletion docs/sdk-and-tools/sdk-dapp/sdk-dapp.md
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ Use:

- `useGetPendingTransactions` to get a list of all pending transactions.
- `useGetSuccessfulTransactions` to get a list of all successful transactions.
- `useGetFailedTransactions` to get a list of all pending transactions.
- `useGetFailedTransactions` to get a list of all failed transactions.

An especially useful hook called `useGetActiveTransactionsStatus` will keep you updated with the status
of all transactions at a certain point in time.
Expand Down

0 comments on commit 806d2fa

Please sign in to comment.