Skip to content

feat: add advanced example of contract state migration #2

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

Merged
merged 5 commits into from
Dec 17, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
toolchain: 1.81.0
default: true
target: wasm32-unknown-unknown

Expand Down
76 changes: 61 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ members = [
"enum-updates/update",
"self-updates/base",
"self-updates/update",
]
"advanced-multi-version-updates/v1",
"advanced-multi-version-updates/v2",
"advanced-multi-version-updates/v3",
]
11 changes: 11 additions & 0 deletions advanced-multi-version-updates/v1/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "advanced-v1"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
near-sdk = "5.6"
79 changes: 79 additions & 0 deletions advanced-multi-version-updates/v1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Guest Book Contract

The smart contract stores messages, keeping track of how much money was deposited when adding the message.

```rust
#[payable]
pub fn add_message(&mut self, text: String) {
let payment = env::attached_deposit();
let premium = payment >= POINT_ONE;
let sender = env::predecessor_account_id();

let message = PostedMessage {
premium,
sender,
text,
};
self.messages.push(message);
self.payments.push(payment);
}
```

<br />

# Quickstart

## 1. Build and Deploy the Contract

Install [`cargo-near`](https://github.com/near/cargo-near) and run:

```bash
# from repo root
cd advanced-multi-version-updates/v1
cargo near build --no-docker
```

Build and deploy:

```bash
# `update-migrate-rust-advanced-multiversion-updates.testnet` was used as example of <target-account-id>
cargo near deploy --no-docker <target-account-id> without-init-call network-config testnet sign-with-keychain send
```

## 2. How to interact?

_In this example we will be using [NEAR CLI](https://github.com/near/near-cli)
to intract with the NEAR blockchain and the smart contract and [near-cli-rs](https://near.cli.rs)
which provides more control over interactions and has interactive menus for subcommands selection_

### 1. Add a Message

```bash
# NEAR CLI
near call <target-account-id> add_message '{"text": "a message"}' --amount 0.1 --accountId <account>
# near-cli-rs
near contract call-function as-transaction <target-account-id> add_message json-args '{"text": "a message"}' prepaid-gas '100.0 Tgas' attached-deposit '0.1 NEAR' sign-as <account> network-config testnet sign-with-keychain send
```

<br />

### 2. Retrieve the Stored Messages & Payments

`get_messages` and `get_payments` are read-only method (`view` method)

```bash
# NEAR CLI
near view <target-account-id> get_messages
# near-cli-rs
near contract call-function as-read-only <target-account-id> get_messages json-args {} network-config testnet now
# NEAR CLI
near view <target-account-id> get_payments
# near-cli-rs
near contract call-function as-read-only <target-account-id> get_payments json-args {} network-config testnet now
```

<br />

### 3. Continue in the V2 Folder

Navigate to the [v2](../v2/) folder to continue
4 changes: 4 additions & 0 deletions advanced-multi-version-updates/v1/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[toolchain]
channel = "1.81.0"
components = ["rustfmt"]
targets = ["wasm32-unknown-unknown"]
81 changes: 81 additions & 0 deletions advanced-multi-version-updates/v1/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use near_sdk::{near, BorshStorageKey};

use near_sdk::borsh::BorshSerialize;
use near_sdk::json_types::{U128, U64};
use near_sdk::store::Vector;

use near_sdk::{env, AccountId, NearToken};

const POINT_ONE: NearToken = NearToken::from_millinear(100);

#[derive(BorshSerialize, BorshStorageKey)]
#[borsh(crate = "near_sdk::borsh")]
pub enum StorageKey {
Messages,
Payments,
}

#[near(serializers=[json, borsh])]
pub struct PostedMessage {
pub premium: bool,
pub sender: AccountId,
pub text: String,
}

#[near(contract_state)]
pub struct GuestBook {
messages: Vector<PostedMessage>,
payments: Vector<NearToken>,
}

impl Default for GuestBook {
fn default() -> Self {
Self {
messages: Vector::new(StorageKey::Messages),
payments: Vector::new(StorageKey::Payments),
}
}
}

#[near]
impl GuestBook {
#[payable]
pub fn add_message(&mut self, text: String) {
let payment = env::attached_deposit();
let premium = payment >= POINT_ONE;
let sender = env::predecessor_account_id();

let message = PostedMessage {
premium,
sender,
text,
};
self.messages.push(message);
self.payments.push(payment);
}

pub fn get_messages(
&self,
from_index: Option<U128>,
limit: Option<U64>,
) -> Vec<&PostedMessage> {
let from = u128::from(from_index.unwrap_or(U128(0)));

self.messages
.iter()
.skip(from as usize)
.take(u64::from(limit.unwrap_or(U64::from(10))) as usize)
.collect()
}

pub fn get_payments(&self, from_index: Option<U128>, limit: Option<U64>) -> Vec<U128> {
let from = u128::from(from_index.unwrap_or(U128(0)));

self.payments
.iter()
.skip(from as usize)
.take(u64::from(limit.unwrap_or(U64::from(10))) as usize)
.map(|x| U128(x.as_yoctonear()))
.collect()
}
}
11 changes: 11 additions & 0 deletions advanced-multi-version-updates/v2/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "advanced-v2"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
near-sdk = "5.6"
Loading
Loading