💧

Suiでブロックチェーンを学ぼう

に公開

1.Suiについて

Suiは、MystenLabsが開発したL1のブロックチェーンです。

2022年にテストネットがローンチされて、2023年5月にメインネットがリリースされました。

Suiが誕生した背景として2019年にMeta(旧facebook)からDiemというプロジェクトが発表されました。しかし当時の規制が厳しくDiemは2022年に中止になりました。

そのDiemプロジェクトのメンバーがMetaから独立して立ち上げたプロジェクトがSuiです。

独自のプログラミング言語「Sui Move」を使用し、オブジェクト指向モデルで設計されています。
オブジェクトモデルで設計することで、デジタル資産の所有を安全に管理することができます。

2.環境構築

Suiをインストールします。

Mac

brew install sui

Homebrewのインストールはこちら
https://brew.sh/ja/

 
Windows

choco install sui

Chocolateyのインストールはこちら
https://zenn.dev/kazuma_r5/articles/a6d2608446ebdf

Windowsのトラブルシューティング
  1. PowerShellを再起動
  2. 管理者権限で実行
  3. 環境変数にPATHが追加されているか確認

 

インストールできたことを確認します。

sui --version

Suiのネットワークに接続します。

sui client

設定ファイルを作成します。
yを押してEnterを押します。

Config file ["<PATH-TO-FILE>/client.yaml"] doesn't exist, do you want to connect to a Sui Full node server [y/N]?

デフォルトのTestnetに接続するため、そのままEnterを押して進めます。

Sui Full node server URL (Defaults to Sui Testnet if not specified) :

署名方式を設定します。
0を入力して、Enterを押します。

Select key scheme to generate keypair (0 for ed25519, 1 for secp256k1, 2 for secp256r1):

ウォレットアドレスが作成されました。
「Secret Recovery Phrase」は後ほど使うのでメモします。

Generated new keypair for address with scheme "ed25519" [0xb9c83a8b40d3263c9ba40d551514fbac1f8c12e98a4005a0dac072d3549c2442]
Secret Recovery Phrase : [cap wheat many line human lazy few solid bored proud speed grocery]
Devnetの接続はこちら

Devnetの環境を追加します。

sui client new-env --alias devnet --rpc https://fullnode.devnet.sui.io:443

 

Devnetに切り替えます。

sui client switch --env devnet

Devnetでコインを取得します。

sui client faucet

 

接続している環境を確認します。

sui client envs

テストネットがアクティブになっていればOKです。

╭─────────┬─────────────────────────────────────┬────────╮
│ alias   │ url                                 │ active │
├─────────┼─────────────────────────────────────┼────────┤
│ testnet │ https://fullnode.testnet.sui.io:443 │ *      │
╰─────────┴─────────────────────────────────────┴────────╯

テストネットに接続できました。
続いてウォレットを追加します。

リンクにアクセスします。
https://slush.app/

Chromeの拡張機能にウォレットを追加します。
「DOWNLOAD FOR CRHOME」をクリックします。

Chromeに追加します。

More Optionsをクリックします。

Import existing from passphraseをクリックします。

 

先ほど出力されたリカバリーフレーズを入力します。

Secret Recovery Phrase : [cap wheat many line human lazy few solid bored proud speed grocery]

パスワードを設定します。

変更せずデフォルトのままで進めます。

ウォレットが作成できました。

次にSuiのテスト用コインを取得していきます。

Settingsをクリックします。

SettingsのNetworkから、Testnetを選択します。

AboutにあるRequest Sui Tokenをクリックします。

ウォレットを接続して、リクエストします。

テスト用のコインが取得できました。

以上で環境構築は完了です。

 

Sendをクリックします。

赤枠をクリックします。

任意の数量と送信先のアドレスを入力して、Sendをクリックして完了です。

コインの送信履歴は、ウォレットから確認できます。

こちらは他のアドレスから、0.7SUIを受け取っています。
コインのオブジェクトが相手から自分のアドレスに転送されたことが確認できます。

以下のコマンドを実行してCLIからも手持ちのコインを確認できます。

sui client gas

NFTを作成しよう

この章ではNFTを作成していきます。

用意した画像をストレージにアップロードします。
この記事では、pinataを使います。

画像はpublicにします。

https://app.pinata.cloud/auth/signin

パッケージを作成します。

sui move new handson_nft

フォルダーを移動します。

cd handson_nft/

VSCodeを開きます。

code .

sources/handson_nft.moveのファイルを開きます。

オンラインエディタはこちら
https://vscode.dev/?vscode-lang=ja

 

コードを貼り付けます。

handson_nft.move
module handson_nft::handson_nft;

use std::string;
use sui::package;
use sui::display;

// NFTオブジェクトを作成
public struct NFT has key, store {
    id: UID,
    image_url: string::String,
}

public struct HANDSON_NFT has drop {}

// 初期化して、NFTオブジェクトを作成
fun init(otw: HANDSON_NFT, ctx: &mut tx_context::TxContext) {
    let keys = vector[
        string::utf8(b"name"),
        string::utf8(b"image_url"),
        string::utf8(b"description"),
        string::utf8(b"creator"),
    ];

    let values = vector[
        string::utf8(b"My NFT"),
        string::utf8(b"{image_url}"),
        string::utf8(b"Sui Handson NFT"),
        string::utf8(b"Unknown Sui Fan"),
    ];

    let publisher = package::claim(otw, ctx);

    let mut display = display::new_with_fields<NFT>(
        &publisher, keys, values, ctx
    );

    display.update_version();

    transfer::public_transfer(publisher, tx_context::sender(ctx));
    transfer::public_transfer(display, tx_context::sender(ctx));
}

// NFTを発行
public fun mint(image_url: string::String, ctx: &mut tx_context::TxContext): NFT {
    let nft = NFT {
        id: object::new(ctx),
        image_url,
    };
    nft
}

// NFTを発行して実行したアカウントに転送(
#[allow(lint(self_transfer))]
public fun mint_and_transfer(image_url: string::String, ctx: &mut tx_context::TxContext) {
    let nft = mint(image_url, ctx);
    transfer::transfer(nft, tx_context::sender(ctx));
}

publishコマンドでテストネットに公開します。

sui client publish

必要なログを抜粋しています。

╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes                                                                                                              │
├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects:                                                                                                            │
│  ┌──                                                                                                                        │
│  │ ObjectID: 0x1f3701e130ac37d9d58f64351b3227f056db4f8f7348261b54e2531efc1889a3                                             │
│  │ Sender: 0xbae8b77531cb9e064a2189ee034bad6bb68ca84ff15f7c8cf8959ebbba63ddd9                                               │
│  │ Owner: Account Address ( 0xbae8b77531cb9e064a2189ee034bad6bb68ca84ff15f7c8cf8959ebbba63ddd9 )                            │
│  │ ObjectType: 0x2::package::UpgradeCap                                                                                     │
│  │ Version: 78                                                                                                              │
│  │ Digest: AXbb57F8TTrVG7ThiFXEs1SDSgjZwvZNjGsdJkdpkLZi                                                                     │
│  └──                                                                                                                        │
│  ┌──                                                                                                                        │
│  │ ObjectID: 0x56da3b08f9fa3c0fcac752d47a41419c99554883a1d2d3fdc2e23c7f8e13bd9b                                             │
│  │ Sender: 0xbae8b77531cb9e064a2189ee034bad6bb68ca84ff15f7c8cf8959ebbba63ddd9                                               │
│  │ Owner: Account Address ( 0xbae8b77531cb9e064a2189ee034bad6bb68ca84ff15f7c8cf8959ebbba63ddd9 )                            │
│  │ ObjectType: 0x2::package::Publisher                                                                                      │
│  │ Version: 78                                                                                                              │
│  │ Digest: 2Tnb9hTyxFYaxGaQYmyHgB5jwJXCUr1TGdrwtTkhvUJE                                                                     │
│  └──                                                                                                                        │
│  ┌──                                                                                                                        │
│  │ ObjectID: 0x7ad09bda2fa55b170eb730bac7ecd98a1a6117a64514ed574e1da6dab3ec01e8                                             │
│  │ Sender: 0xbae8b77531cb9e064a2189ee034bad6bb68ca84ff15f7c8cf8959ebbba63ddd9                                               │
│  │ Owner: Account Address ( 0xbae8b77531cb9e064a2189ee034bad6bb68ca84ff15f7c8cf8959ebbba63ddd9 )                            │
│  │ ObjectType: 0x2::display::Display<0x9d1204366fb0338331aa82e71f55559178c1db3cd62d1fc7ab98309fbb0c977d::handson_nft::NFT>  │
│  │ Version: 78                                                                                                              │
│  │ Digest: pWREXsBjKAm5ST2nqoYCYBnN7AyawEm5Ed4JUQ5VFLG                                                                      │
│  └──                                                                                                                        │
│ Mutated Objects:                                                                                                            │
│  ┌──                                                                                                                        │
│  │ ObjectID: 0x2c14f5cead225473d228d341ebc1582982d84b1b6ca63ad0e8e5f22159b8ed34                                             │
│  │ Sender: 0xbae8b77531cb9e064a2189ee034bad6bb68ca84ff15f7c8cf8959ebbba63ddd9                                               │
│  │ Owner: Account Address ( 0xbae8b77531cb9e064a2189ee034bad6bb68ca84ff15f7c8cf8959ebbba63ddd9 )                            │
│  │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI>                                                                               │
│  │ Version: 78                                                                                                              │
│  │ Digest: 2gZin2SoSYgZxrTSpSqjVDu1oJvkqPQ8fSHh6dKBdXy5                                                                     │
│  └──                                                                                                                        │
│ Published Objects:                                                                                                          │
│  ┌──                                                                                                                        │
│  │ PackageID: 0x9d1204366fb0338331aa82e71f55559178c1db3cd62d1fc7ab98309fbb0c977d                                            │
│  │ Version: 1                                                                                                               │
│  │ Digest: GdYPgw7Rc9ZyodhJg7DS2vgjprqDKhGHNvYHJzx17rCm                                                                     │
│  │ Modules: handson_nft                                                                                                     │
│  └──                                                                                                                        │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

NFTを発行する関数を実行します。

sui client call --package <YOUR_PACKAGE_ID> --module handson_nft --function mint_and_transfer --args <IMAGE_URL>

ウォレットを確認するとNFTが発行されていることが確認できます。

以上で終了です。
お疲れ様でした!

Discussion