🏅

テイラーワークス社内実験「Play! Web3」について#3:〜SoulBound Token編(ソウルバウンドトークン・SBT)〜

2023/07/28に公開

こんにちは。テイラーワークスの澤田です。
プロダクトチームでWeb3エンジニアをやっています。

Web3を中心に、気になるテーマについてブログにまとめていけたらと思います。

「Play! Web3」というWeb3体験まつり(社内実験)で扱った技術について紹介する連載3回目。

今回は SoulBound Token について紹介したいと思います。

※ブログ内で引用しているコードは、社内で実験したものを紹介しています。安全性や脆弱性の検査は行っていません。参考にされる場合は、ご自身の責任の元、ご対応ください

連載一覧

SoulBound Token(ソウルバウンドトークン・SBT)って何?

前回のブログで行った NFTの説明 を引用します。

デジタルアセット(アート作品、ゲームアイテムやキャラクター、コレクターアイテムなどなど)の所有情報を管理し、売買などによって、所有者が変わる仕組みを持っているものが、NFT(Non-Fungible Token)です。

一方、SoulBound Token は 所有者を変更できない仕組みにしたトークンのスマートコントラクト です。スマートコントラクトによっては、所有者を回数制限付きで変更できるようになっていたり、第三者による承認によって所有者の変更が行えるものもありますが、基本は所有権の移転ができないようになっています。

Tailor Worksでは、Web3 の新しい活用方法として、SoulBound Token を実験してみました。

規格としては複数登録されていて、どういった実装が望ましいのか、運用に合わせて仕様を選択していく形になると思います。(参考として、リンクを列挙しましたが、全部を理解する必要はないかなと思います)

社内のすごい人に「表彰状」や「バッジ」を贈ろう

SoulBound Token の一例として、表彰状やバッジをスマートコントラクトで実装してみました。ブロックチェーンに記録されることで、情報が確実に残るという状態の体験です。

今回の実装では、バッジや表彰状にメッセージを簡単に入れられるように実装しています。

テックブログ発行記念

SoulBound Token

社内で発行された SoulBound Token です。
画像のアップロードや画像への文字入れ処理をウェブに実装していますので、簡単な手順で SoulBound Token を Mint できます。

(余談)バッジ or バッヂ

社内実験中は「バッヂ」を使用していたのですが、ブログで紹介するにあたり、たくさん検索に引っかかった用語のほうが良いかも、という考えでブログ内だけ「バッジ」としています。

ちなみにこのブログを書いているときのGoogle検索の結果数ですが、このような違いがありました。

  • 「バッジ」で検索 ・・・ 約58,100,000件
  • 「バッヂ」で検索 ・・・ 約3,710,000件

所有者を変更できないようにするには?

基本的な実装はNFT(ERC721)ベースで行っています。簡単に実装するために 所有者の変更に関連する関数を無効化しています。

↓transfer関連のメソッドの実装を空にして、実行できないようにしています。

    // ---------------------------------------------
    // Disable unnecessary functions
    // ---------------------------------------------
    function approve(address to, uint256 tokenId) public view override {}

    function setApprovalForAll(address operator, bool approved) public view override {}

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public view override {}

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public view override {}

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public view override {}

独自に実装した機能

SoulBound Tokenとしては、基本的な実装をしていますが、表彰状やバッジを作成する際にお祝いとして Tailor Works Token をプレゼントできるようにしています。

トークンをギフトできる

お祝いの気持ちを示すために、mint() ではなく、award() という関数名、イベントも Awarded() にしています。

    function award(
        address awardee,
        string memory uri,
        uint256 giftAmount
    ) external onlyTwMember whenNotPaused returns (uint256) {

        require(isTwTokenMember(awardee), 'Must be a member of TW Token');

        bytes memory data;

        // Author determines the value of the work and pays for it
        if (0 < giftAmount) {
            bool isPaymentSuccessful = twToken.pay(msg.sender, awardee, giftAmount);
            require(isPaymentSuccessful, 'Payment Failure');
        }

        tokenIdCounter.increment();
        uint256 tokenId = tokenIdCounter.current();

        _safeMint(awardee, tokenId, data);
        _setTokenURI(tokenId, uri);

        uint256 awardedAt = block.timestamp;

        emit Awarded(msg.sender, awardee, tokenId, uri, awardedAt);

        return tokenId;
    }

スマートコントラクトの解説

補足・オンチェーン・オフチェーンって?(テイラーワークス社内実験「Play! Web3」について#2:〜NFT編〜)

オンチェーンで管理した内容・項目

  • トークンID(登録No.)
  • 発行者のイーサリアムアドレス
  • 保有者のイーサリアムアドレス
  • 画像のURI(S3のオブジェクトキー)

オフチェーンで管理した内容・項目

画像は AmazonS3 でファイルを管理し、Amazon CloudFront で配信しました。作成時に入力した項目は画像内に反映させていますので、テキスト情報は管理していません。

ふりかえり

イベントがスタートしてある程度バッジや表彰状が発行されてから気がついたことなのですが、作成時にプレゼントしたトークンの量をスマートコントラクト内に記録しておけばよかったと思っています。

スマートコントラクトの実装は公開後に変更できないため、なるべく必要と思われる要素を事前に検討し、それに基づいて実装してはいたものの、、検討だけではわからないこともありますよね。

このあたりは何度かテスト運用を行って、不足している機能がないか確認するのが良いかなと思います。

また、バージョンアップができるようにスマートコントラクトを実装しておくことで、そういった問題を回避できるかもしれません。

おわりに

今回は、テイラーワークスの社内のWeb3体験イベント「Play! Web3」で行った SoulBound Token について紹介しました。

次回は スマートコントラクトを使用したユーザー認証(認証スマートコントラクト) について紹介したいと思います。

テイラーワークスは、エンジニア採用強化中

テイラーワークスは、エンジニア採用強化中です!
▼少しでも興味をお持ちいただけましたら、採用ページもチェックしてみてください
https://tailorworks.co.jp/careers

Tailor Worksテックブログ

Discussion