はじめに
ゲームに特化したブロックチェーンなどの話題などが出てきて、何かに特化した専用チェーンという話題がでています。ブロックチェーン自体をいわゆるプラットフォームという位置づけと捉えた場合、専用チェーンは重要な取り組みとなりますが、ブロックチェーン自体はコンセンサスアルゴリズムはじめ様々案実装が必要となるのと同時に、チェーン単体では実際のサービスと接続することは難しく、WalletやSDKなどチェーンに紐づく仕組みが必要となり、独自チェーンの実装はハードルが高いことが現状です。そういう中での選択肢として、Substraiteを立ちあげてNFTで用いられるERC721の発行を試してみます。数年前に、何度か試したことがあったのですが、チュートリアルなども色々変わってしまっているので、あらためてメモ書きとして残しておきます。
概要
substrate + ink!
Substrateでは、Palletというコンポーネント群を好みに応じて選んで使える機構がありますが、
その中に入っているink!というコンポーネントを利用します。
(以前は、SRMLという名前だったのを覚えてますが、今は、Palletという名前に変わった様子)
https://www.giters.com/JoshOrndorff/recipes/issues/94
ink!自体は、Substrateにスマートコントラクトを展開するためのeDSLサービスです。
https://wiki.haskell.org/Embedded_domain_specific_language
ink! > Wasm
Ethereumでも、次期バージョンでは、現状のEVMから、eWASMに取って代わろうとしていますが、ink!の中では既にWasmが使われています。
https://paritytech.github.io/ink-docs/ink-vs-solidity
そういった理由からEthereumで慣れたsolidityもSubstrateでも使えるとか。公式によるとcargoでsolangをインストールすればよさげ。
https://solang.readthedocs.io/en/latest/index.html
ただ、よほど既存のsolidity資源があるとかであれば別ですが今回は新規なので、普通にRustで書くことにします。
cargo install --git https://github.com/hyperledger-labs/solang --tag m8
ERC721をlocalにinstallする手順
環境構築
//Rustのインストール
curl https://sh.rustup.rs -sSf | sh
source ~/.cargo/env
rustup default stable
rustup update
//Rustのアップデート
rustup update nightly
//wasmのインストール
rustup component add rust-src --toolchain nightly
rustup target add wasm32-unknown-unknown --toolchain nightly
rustc --version
rustup show
//スマートコントラクトCLIのインストール
cargo install cargo-contract --vers ^0.17 --force --locked
//スマートコントラクトノードのinstall
cargo install contracts-node --git https://github.com/paritytech/substrate-contracts-node.git --tag v0.6.0 --force --locked
ERC721コントラクトの作成
//新しいコントラクトを作成する
cargo contract new erc721
cd erc721
cargo +nightly test
//lib.rsにcontractをコピー
https://github.com/paritytech/ink/blob/master/examples/erc721/lib.rs
//いくつか置き換え
use ink_storage::{
traits::SpreadAllocate,
lazy::Mapping,
};
ink_lang::codegen::initialize_contract
//ビルドする
cargo +nightly contract build
//コントラクトようのノードをrunさせる
substrate-contracts-node --dev --tmp
ERROR: wasm-opt not found! Make sure the binary is in your PATH environment.
We use this tool to optimize the size of your contract's Wasm binary.
wasm-opt is part of the binaryen package. You can find detailed
installation instructions on https://github.com/WebAssembly/binaryen#tools.
//上記エラーが出た場合はwasm-optがはいってないのでinstallする
$ npm i wasm-opt -g
deploy
polkadot.js.orgからでもok
1.erc721.contractをupload
2.aliceでdeploy
call
alice->bobへのerc721のtransfer
TestNetに展開してみる
現在うごいているtestnetの中でcontractが動かせるチェーンは限られているので、今回はinkのdocにも書かれているcanvasのtestnetで動かしてみる
1.PolkadotExtensionをchromeにいれてアカウントを作成
(またはpolkadotでアカウントを作成)
https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-canvas-rpc.polkadot.io#/accounts
2.faucetでトークンをもらう
riot.imという分散型のチャットサービスに登録する必要がある。(facebookやtwitterまたはemailのログインに対応)
公式に書いてあったCanvasTestNetFaucetはRococoというところに統合されたと書かれていたので、そっちで請求する
The Canvas testnet has been migrated to Rococo as a parachain! The testnet will now use Rococo's native token, ROC, which can be retrieved from the
Rococo Testnet Faucet room.
こっちらしい
https://riot.im/app/#/room/#rococo-faucet:matrix.org
!drip アドレスとチャットで送信すると送られてくる
3.canvasに受け取ったトークンをTeleportする
4.ネットワークをcanvasに切り替え
5.testnetにdeployする
あらためて、contracts-uiから接続。(polkadot.js.orgからでもok)
ネットワークをlocalからcanvasに切り替えを行う。
polkadot-extensionに登録したアドレスからコントラクトを実行する
https://paritytech.github.io/contracts-ui/#/add-contract
deployはtestnetの方法と同じ。
Add New Contracts -> erc721.contractをアップロードして実行するだけでok。
(参考)
5DERJfX1cpfmQCGVKdsnWPxAnfRtz1S3YYQ6pE2eXNLRhRGU
その他
Stringが使えない?
下記理由から使えないそうです。
Minimizing storage usage of your contract is a best practice and you should only persist items which you need to derive state transitions in your contract.
Vecなどバイト列にして載せるべし