ブラウザでEthreumのトランザクションを大量に発行したい

# 大量の承認ポップアップが...
Metamask経由でEthreumのトランザクションを発行しようとすると承認ポップアップがでてきます。
大量のトランザクションを発行しようとすると、発行したトランザクション分ポップアップを承認しなければならず、とても手間です。
特に、信頼しているサイト(自分で作っているサイト)であればわざわざ承認する必要はありません。(ガス価格の調整は必要かもしれませんが...)
なので、承認ポップアップを回避して大量にトランザクションを発行する方法を考えてみました。
# Metamskの設定を見直す
Metamaskの設定でポップアップ承認をスキップできる設定があれば全て解決します！
ということで、~~絶対にないと思いますが~~ 設定がないか確認してみました。

|項目|設定できる内容|内容|
|:--|:--|:--|
|General|Currency Conversion|アカウント画面で表示する「法的通貨」の設定|
||Primary Currency|アカウント画面で表示するETHと法的通貨の表示順|
||Current Language|言語設定|
||Blockies Identicon|アカウントのアイコンの見た目設定|
|Connections|Add Site|Metamas連携許可サイトの追加|
||Connected|Metamask連携許可済のサイト一覧|
||承認データのクリア|Metamask連携許可済みサイト全て削除|
|Advanced|State Logs|公開鍵とかトランザクションの履歴をJSONファイルでダウンロード|
||Sync with mobile|MetaMaskモバイルアプリと連携できるらしい|
||アカウントをリセット|トランザクション履歴削除|
||Advanced gas controls|トランザクション承認画面でガス代設定ができるようになる。(わざわざ設定画面を開く必要がなくなる)|
||Show Hex Data|16進数データの表示。どこの部分が変更されているかわからなかった...|
||Show Conversion on Testnets|テストネットでコンバージョンを表示。これもどこの部分が変更されているかわからなかった...|
||Auto-Logout Timer (minutes)|Metamaskが自動でログアウトするまでの時間(分)|
|Contacts|My Wallet Accounts|アカウント名や公開鍵の設定など|
|Security & Privacy|パスフレーズを表示|Walletのニーモニックの表示|
||Show Incoming Transactions|着信系のトランザクション表示|
||Participate in MetaMetrics|MetaMesksに参加して、MetaMaskの改善にご協力くださいON/OFF|
|ネットワーク|Add Network|ネットワークの追加|
|About||利用規約など|

思った通り承認ポップアップなし、みたいな設定はありませんでした。
次の方法を考えます。

# 別のWalletアプリを使う
Metamaskがダメだとしても、他のWalletアプリなら！
ということで、いくつかWalletアプリを調べてみました。

|Wallet名|サイト|備考|
|:--|:--|:--|
|Dapper|https://www.meetdapper.com/|メアドと本人確認コード送信用に電話番号の入力が必要。|
|portis.io|https://wallet.portis.io|メアドのみで作成可|
|Fortmatic|https://fortmatic.com/|本人確認コード送信用に電話番号の入力が必要。アプリ連携用にGitHubのアカウントが必要|
Dapper、Fortmaticについては電話番号入力があり、なんとなく不安なので作成しませんでした。
電話番号未利用で作成することができたportis.ioを使ってトランザクション発行をしてみたいと思います！
# portis.ioでトランザクションを発生させる
[portis github](https://github.com/portis-project/web-sdk)、[portis getting started](https://docs.portis.io/#/) を参考にwalletを連携させていきます。

作業的には、[ダッシュボード](https://dashboard.portis.io/)でアプリキーを作成して、連携部分のソースをコピペするだけなので簡単です。
カスタムノードも対応しています。

```javascript:Web3連携部分
import Web3 from "web3";
import Portis from '@portis/web3';

async portis(){
  // カスタムノードの場合
  // const myLocalPOANode = {
  //   nodeUrl: 'https://HTTP://0.0.0.0:7545',
  //   chainId: 5777,
  // };
  // const portis = new Portis('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', myLocalPOANode);

  // Rinkebyの場合    
  const portis = new Portis('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', "rinkeby");
  const web3 = new Web3(portis.provider);

  // 作成したweb3を利用してstateなど設定
  await this.stateSetting(web3)
}

```

ではトランザクションを発行してみます。

![Screenshot_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359665/598255a5-f991-26fc-3a80-1fec62a759b5.png)

承認ポップアップがでました...が、「Trust this app」という気になるスイッチが！
[リンク先](https://www.portis.io/learning#trust-this-app)を確認すると、「アプリを信頼すると**1時間あたり1ドル**まではトランザクションの承認不要で実行できるよ！」
との記載が！

実際に信用してトランザクションを発行してみると...承認不要でトランザクションを発行することができました！
![Screenshot_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359665/749041ff-987f-5bf0-56ac-a706c86db26b.png)

でも、1ドルまでは少なすぎるので、別の方法を考えます。

# 結論、Walletアプリを使わない
トランザクション承認なしで送れてしまうと、悪意のあるサイトなどで大量にETHを支払わされることにもなりかねないので、承認なしWalletやサービスはきっと存在しないと思います。(portis.io のように上手く承認を回避するものもあるかもしれませんが)

ということで、Walletアプリを使わずトランザクションを発行していきます。
Infura経由でプロバイダーを取得、秘密鍵をWalletに設定しトランザクションを発行します。

```javascript:Infra連携&アカウント設定部分
async infra(){
    // infuraよりプロバイダー取得
    const provider = new Web3.providers.HttpProvider(
      "https://rinkeby.infura.io/v3/{PROJECT ID}"
    );
    const web3 = new Web3(provider);
    // 秘密鍵よりアカウント情報作成
    const account = await web3.eth.accounts.privateKeyToAccount("0x{Private Key}");
    // 作成したアカウント情報をwalletに追加
    await web3.eth.accounts.wallet.add(account);
    // 作成したweb3、accountを利用してstateなど設定
    await this.setState({web3: web3, address: account.address})   
}
```
```javascript:トランザクション発行部分
// トランザクション発行
async send(){
    await this.state.contract.methods.set(1).send({ from: this.state.address , gas: 1500000, gasPrice: '20000000000'})
    await this.state.contract.methods.set(2).send({ from: this.state.address , gas: 1500000, gasPrice: '20000000000'})
    await this.state.contract.methods.set(3).send({ from: this.state.address , gas: 1500000, gasPrice: '20000000000'})
    await this.state.contract.methods.set(4).send({ from: this.state.address , gas: 1500000, gasPrice: '20000000000'})
}
```
承認なしで複数のトランザクション発行することができました！~~ポップアップなど載せる画像などなく寂しい...~~

# 感想
承認なしで発行できるのは便利ですが、秘密鍵の設定とガス価格をわざわざ自分で計算する必要があるのなら、大量にトランザクションを発行する必要がないように作る & Walletアプリを使うのが現実的だなと思いました。