EthereumのERC721トークンで実物資産管理とレンタルサービスを行う


ERC721 GPU Rental
https://erc721-gpu-rental.firebaseapp.com/

Mediumのほうでも、背景などの説明をしています。
https://medium.com/@lte/%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%83%81%E3%82%A7%E3%83%BC%E3%83%B3%E3%81%A7%E7%89%A9%E6%A8%A9%E7%AE%A1%E7%90%86-gpu-%E3%83%AC%E3%83%B3%E3%82%BF%E3%83%AB-%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%83%86%E3%82%B9%E3%83%88%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%B3-77762922c37c


本プロジェクトは、shoraさんのプロジェクトをベースとしています。
https://qiita.com/shora_kujira16/items/7e25f89311ae785fc830


ERC721 GPU Rentalは、基本的には以下のフローで動作します。

(1) ログインする
  事前の準備として、Rinkebyアカウントと、emailアドレスかgithubのアカウントを用意します。
  MetaMaskなどでWalletを有効化した上で、SinInをクリックし、
  emailとパスワードを入力してログインするか、githubのOAuthで認可を受けるばOKです。
  この時点で、ユーザーのWalletのアドレスとemailが紐づけられ、あとの連絡で使用します。
  
(2) オーナーとなる人が実物資産を登録する。
  右下の(+)をクリックし、写真を撮ってアップロードすると、その写真のURLをERC721に紐づけます。
  ZepperinSolidity1.xのERC721をカスタマイズしたトークンに、
  RareBitsのMetadata Formatに準拠する形でmint()しています。
  https://docs.rarebits.io/docs/listing-your-assets
  
```
  function mint(uint256 _tokenId, string _metadata) external
```

  ERC721ではmint()は誰でもできるため、誰でもownerになれますが、
  OpenZepperin2.xのERC721Mintableでは、mint権限がMinterRoleになっていて、権限管理がしっかりしています。

(3) 登録されたAssetを欲しい、もしくはレンタルしたい人が、Request(+message)を送付する。
  Assetのオーナーだけが、そのRequestの内容と、Requestした人のプロフィールを参照できます。
  
(4) オーナーがRequestした人に、Assetを譲渡する、もしくは期間限定で貸し出す。
  Assetを譲渡する場合、ERC721のtransferを行うだけです。
  期間限定で貸し出す場合、ERC721の上に作ったlendメソッドをたたきます。 
 
```
  function lend(uint256 _tokenId, uint256 deadline, address to) external onlyOwnerOf(_tokenId)
```

(5) 期限が来たら、オーナーが貸し出したAssetを返却してもらう。
  ERC721の上に作った返却用のメソッドをたたきます。

```
  function returnLendOwner(uint256 _tokenId) external onlyLendOwnerOf(_tokenId)
```


## ERC721でレンタル？

レンタルって聞くと、借りた人が返すんだろうなーって思いますが、
借りた人が返すためには、返却メソッドみたいのを叩いて手数料を負担する必要があり、
返却されない可能性があります。
Ethereumには次元式の発火処理みたいのが作れないため、
第三者に報酬を与えてcronみたいに期限指定して実行してもらう案もあるようです。
※例えばEthCronみたいなサービスにmethodを登録しておくと、指定した時刻にメソッドが実行され、
メソッドを実行した人に報酬が支払われるみたいな。

その問題を解決するため、指定した期限以降に限り、
LendしたOwnerが強制的にownerを戻すメソッドを用意しました。
ERC721としては、たとえレンタルであろうと、ownerをtransferしないと
ERC721として動作しないため、レンタル処理の中ではtransferを行っています。
ですがownerだから何でもできるというわけではなく、LendOwnerが設定されていれば
将来的には返却する必要があります。
そのため、レンタルした人Aが、他の人Bにtransferすることはできるため、
Bさんは期限が過ぎたらLendOwnerにownerを戻されることになります。

レンタルしたownerのapproveなしにどうやってtransferするのかというと、
ZepperinSolidity1.xでは、tokenApprovesはinternalで定義されているため、
継承したメソッドから、approveを操作することができます。
※OpenZepperin 2.xではprivateに変更されているため出来ない。

```
   tokenApprovals[_tokenId] = msg.sender;
```

## 実物資産の管理とERC721の課題

実物資産をERC721に登録し、さらには譲渡の際にETHで売り買いを行うようなサービスを行う場合、
いろいろ問題があります。
ERC721は、1号仮想通貨であるEthereumと不特定多数の人と仮想通貨で取引売買できる時点で2号仮想通貨とみなされ、
売買やら仲介するサービスを行うためには仮想通貨交換事業者として免許貰わないといけないと理解しています。

ERC721 GPU Rentalは、仮想通貨の売り買いを仲介するサービスではなく、
あくまでERC721による実物資産登録と、その譲渡およびレンタルを無償で行うため、（※しかもRinkebyで
何も問題はないです。

ですが、Rinkebyからmainnetへ移行できるのか、リーガルチェックは大丈夫なのか？みたいなことは検討しています。
例えばですが、ERC721による実物資産の登録自体は、別に仮想通貨交換事業者なんかなくてもできますし、
交換する行為自体をERC721のDEXへ丸投げすることは可能です。
そのため、1案としてERC721かつRareBitsのmetatdata specへ準拠しています。
要は仮想通貨による交換やら交換の仲介を他サービスに流ればセーフ？なのかな？
こういうサービスに向けた、ERC721向けのオークションサイトやDEXがどんどん出てくるといいですね！

あとは、実物資産の登録や実物資産の譲渡をERC721ベースで行ったとして、
既存の日本の法律へ準拠しているのかっていう問題があります。
その点に関しては、オプショナルになりますが、
ERC721の譲渡の前に、CloudSignで契約書を交わすオプションも試しにつくってみました。
https://app.swaggerhub.com/api/CloudSign/cloudsign-web_api/

シーケンス的には、request貰った後に、
ownerからrequestした人のメアド宛にcloudSignの契約書合意案内が送付される感じですね。

CloudSignは非常に使いやすく便利なのですが、
APIを使うためにはプラン加入必須ですし、契約書の案内を送付するたびに100円取られる？らしいですよ。


## 実装上の注意点

ログイン処理のところで、多少嫌悪感はあるかもしれません。
特にWallet AddressとEmailやらOAuthで紐づけるわけですから。

とはいえ、どこかで本人へつながる情報の管理は必要です。
RareBitsはメアドベースですし、uPortなんかはTelベースです。
こういった個人や法人のIdentityサービスなんかはよく検討されているらしいのですが、
なかなかビジネス的に回すのは難しそうですね。
http://www.nira.or.jp/outgoing/report/entry/n170327_845.html

現状はFirebaseのAuthentificationを使ってやっていますが、
いろいろ問題ありました。
モバイル向けのEthereum Walletて、Firefox+metamask, Cipher, Trustなどがあげられます。

firefoxは良いとして、CipherやTrustは、WebViewを使っており、
google/FirebaseのAuthentificationはWebView経由のOAuthを許さない仕様らしく、
OAuthのRedirectを貰った際にエラーではじくようになっています。
そのためモバイル向けのCipherやTrust向けにemailによる認証を追加しています。


## 今後

実物資産をERC721で管理し、それのtransferやらをリモートから行うことを考えた場合に、
オークションサイトのような仕組みと、郵送後に権利譲渡と支払いがなされるような仕組みは
必須なのかなーと考えています。
代表例としてエスクロー決済があるわけですが、OpenZepperinにも実装済みであるため、
シーケンスが複雑になりますが、エスクロー決済の仮実装は進めています。

他には、位置情報との連携や、部分所有へ拡張していくことなどが挙がっています。

Ethereumの位置情報連携
https://qiita.com/syoyo/items/68858d3adda7cc2f6d8a

Re-FungibleToken
https://magazine.ginco.io/post/topic_refungibletoken/


個人的には、実物資産をもう少し抽象的に扱った、
電子債権のような仕組みも作ってみたいと考えています。
その際のモデルになるのは、日本国としては電子記録債権が該当するでしょうか。
https://www.densai.net/about