8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Gas Station Network でユーザーがGas代を払わずに、トランザクションが実行できるようにする

Last updated at Posted at 2019-11-01

はじめに

先月devcon5に参加した中で、OpenZeppeliの発表のなかでGSNなどの発表があったので、戻ってきてから色々と試してみた覚書です。

unnamed.jpg

ユーザーがDappsを使う際に、少量のGasを必要とすることが、DApssが普及するため障壁の1つであることは、すでに知られている通りです。これを解決するために、OpenZeppelinからGas Station Networkを用いて、これらを解決する一つの手段が提供されています。

(Introductionから引用)
https://forum.openzeppelin.com/t/advanced-gsn-gsnrecipientsignature-sol/1414

Using GSN allows developers to build (d)apps that don’t require end users to have ETH or even have their own wallet.
It does this by allowing for a GSN enabled smart contract to pay for its users transactions itself.
The question then of course is: how does a smart contract determine who is allowed to have their transactions subsidized?
If there is no criteria, it would be trivial for a user in bad faith to exploit a (d)app and obtain unlimited free transactions.
OpenZeppelin provides two sample strategy contracts which can be used to help (d)app developers decide who their recipient contacts are willing to pay for. ...

GSNを使うことで、開発者は"エンドユーザーがWalletにEthereumを必要としないDApps"を構築することができます。
これは、GSN対応のスマートコントラクトが、ユーザートランザクション自体に支払いを行うことを可能にすることで、実現しています。
「スマートコントラクトは、誰がGasの補助を受けることができるのかをどのように決めるのか?」という疑問は至極、当然です。
基準がない場合、悪意のあるユーザーがDAppsを悪用して無制限の無料トランザクションを取得するのは簡単なことです。
OpenZeppelinは、(d)アプリ開発者が受信者の連絡先の支払いを決定するのに役立つ2つのサンプル戦略契約を提供します。

(参考)
https://forum.openzeppelin.com/t/using-gas-station-network-starter-kit-on-a-public-testnet/1429

1–800-Ethereum: Gas Stations Network for Toll Free Transactions
https://medium.com/tabookey/1-800-ethereum-gas-stations-network-for-toll-free-transactions-4bbfc03a0a56

実行サンプル

スクリーンショット 2019-11-01 16.20.04.png

EIP-1613

GSNの基本的なデザインはTabooKeyによって考案され、EIP-1613に提案されています。

alt

使ってみる

1.Development環境で使ってみる

$ npm install -g ganache-cli
$ ganache-cli --deterministic

//プロジェクトのディレクトリを作成する
$ mkdir myproject
$ cd myproject

//GasStationNetworkのkitを展開する
$ npx @openzeppelin/cli@next unpack gsn
$ npx openzeppelin init

//clientアプリケーションを展開する
$ cd client
$ npm run start

//作成する
$ npx openzeppelin create
Nothing to compile, all contracts are up to date.

//質問:コントラクトの名前 (Counterを選択)
? Pick a contract to instantiate Counter
//質問:使用するネットワーク(development を選択)
? Pick a network development
All contracts are up to date
? Do you want to call a function on the instance after creating it? Yes
? Select which function * initialize(num: uint256)

2.Testnet環境で使ってみる

App.jsを書き換える

元は、127.0.0.1:8545に接続されていたものをinfuraに接続するコードを有効にして、127.0.0.1の方のcontextをコメントアウトする。下記のような感じでok。

client/src/App.js
  // get GSN web3
   const context = useWeb3Network(`wss://rinkeby.infura.io/ws/v3/${infuraToken}`, {
     pollInterval: 15 * 1000,
     gsn: {
       signKey,
     },
   });
/*
  const context = useWeb3Network('http://127.0.0.1:8545', {
    gsn: {
      dev: true,
      signKey,
    },
  });
*/

MNEMONICSを生成して、.envに記述する

$ npx mnemonics
attack crane rabbit share proof truck glad next female win regular waste

.envに下記を設定する

$ touch .env
MNEMONIC="attack crane rabbit share proof truck glad next female win regular waste"

アカウントを取得する

$ npx openzeppelin accounts
? Pick a network (Use arrow keys)
❯ rinkeby 

Accounts for rinkeby:
Default: 0x6303b56db2d46fb34EE996E8f3Db58793e7d97dE
All:
- 0: 0x6303b56db2d46fb34EE996E8f3Db58793e7d97dE

このアドレス(Accounts for rinkeby:)にいくらかEthereumを送っておく

Contractをdeployする

$ npx openzeppelin create
? Pick a contract to instantiate Counter
? Pick a network rinkeby
? Do you want to call a function on the instance after creating it? Yes
? Select which function * initialize()

(下記のように怒られたら、GASが足りてない)
✖ Creating instance for contract at 0x706Ffbc6470cBeB7be153750a119140D5E1f9970 and calling 'initialize' with no arguments
insufficient funds for gas * price + value

インスタンスが生成される

✓ Instance created at 0x0385451CfBd7DaDf9506d018E57d2fD4b9CA8604
0x0385451CfBd7DaDf9506d018E57d2fD4b9CA8604

下記リンクから、作成されたインスタンスのアドレスを入力する

Walletと接続するを選択する

スクリーンショット 2019-11-01 11.21.55.png

デポジットを送金しておく

スクリーンショット 2019-11-01 11.23.36.png

CLientを起動

cd client
npm run start

左側がClientで、0Ethereum。右側が作成したCounterContractで、先ほど送った0.5Ethがある状態。IncreaseCounterを押下すると...

スクリーンショット 2019-11-01 11.27.30.png

CounterValueが1になって、IncreaseCounterのトランザクションが成功。

スクリーンショット 2019-11-01 11.28.19.png

remixから実行

RemixやWalletを使うと、Gas=0のトランザクションを作ることはできないため、GSN経由にならずに普通にGasを支払って、コントラクトを実行するような流れになります。

スクリーンショット 2019-11-01 14.58.43.png
1.環境設定
Metamask->Rinkeby
Rimix->Run->Environment:injectedWeb3 Account:Metamaskのaccount

2.Console
cd workspaces/
//実行したいCounter.solの位置を確認
less contracts/Counter.sol 
//remixdを実行
remixd -s ./ --remix-ide https://remix.ethereum.org

3.Remixでlocalhostに接続
->Compile->localhost/contracts/Counter.sol

4.load
Remix->Run->Counter->AtAddress(上記でdeployしたアドレス)

5.試す
getCounter() -> 1

Reactから実行

おしまい

そういえば、OpenZeppelinって、自分の中では、なんとなくSmartContractの雛形みたいなイメージだったのですが、先日devcon5 OsakaのOpenZeppelinのセッションを聞いて、かなりSDK寄りになったというか、開発者が欲しいサービスがどんどんアドオンされているイメージを受けました。GSN以外にも、使いやすそうなものが展開されているようなので、リサーチしてみたいなと思っています。

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?