SubstrateでERC721の発行までのメモ

#はじめに

ゲームに特化したブロックチェーンなどの話題などが出てきて、何かに特化した専用チェーンという話題がでています。ブロックチェーン自体をいわゆるプラットフォームという位置づけと捉えた場合、専用チェーンは重要な取り組みとなりますが、ブロックチェーン自体はコンセンサスアルゴリズムはじめ様々案実装が必要となるのと同時に、チェーン単体では実際のサービスと接続することは難しく、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.txt
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

https://paritytech.github.io/contracts-ui/#/add-contract

polkadot.js.orgからでもok

###1.erc721.contractをupload
![スクリーンショット 2022-02-18 19.40.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/e599fd4f-0046-11ba-f3d5-5d655a52de34.png)


###2.aliceでdeploy
![スクリーンショット 2022-02-18 19.40.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/659b12bd-638f-83b4-6f49-5d06b4a15ecd.png)

##call

###alice->bobへのerc721のtransfer
![スクリーンショット 2022-02-18 19.44.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/35bac65a-403b-ba36-ebc3-0fd0e4e3a3d2.png)


#TestNetに展開してみる
現在うごいているtestnetの中でcontractが動かせるチェーンは限られているので、今回はinkのdocにも書かれているcanvasのtestnetで動かしてみる

https://paritytech.github.io/ink-docs/canvas/


##1.PolkadotExtensionをchromeにいれてアカウントを作成
https://polkadot.js.org/extension/

(または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 アドレスとチャットで送信すると送られてくる

![スクリーンショット 2022-02-19 11.55.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/06c40d58-f419-89e3-f81f-e70eb8efd943.png)

100受け取る
![スクリーンショット 2022-02-19 12.41.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/64ead372-a225-d147-2b61-acf63eda17b6.png)

##3.canvasに受け取ったトークンをTeleportする

![スクリーンショット 2022-02-19 14.06.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/3a9c87e9-d76e-a5af-dc44-8df615530648.png)

![スクリーンショット 2022-02-19 14.00.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/3f608b8f-2d3c-1b65-fa33-cb5e7e91d6b2.png)

##4.ネットワークをcanvasに切り替え

![スクリーンショット 2022-02-19 14.07.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/7096e407-b4e2-043e-650b-38e14c1607e3.png)

##5.testnetにdeployする

あらためて、contracts-uiから接続。(polkadot.js.orgからでもok)
ネットワークをlocalからcanvasに切り替えを行う。
polkadot-extensionに登録したアドレスからコントラクトを実行する
https://paritytech.github.io/contracts-ui/#/add-contract

![スクリーンショット 2022-02-19 14.18.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/c11044ca-0ea2-ad36-981d-b2279766d091.png)


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<u8>などバイト列にして載せるべし


##