LoginSignup
3
1

More than 3 years have passed since last update.

ETHのtestnet faucetを作る with firebase cloud functions

Last updated at Posted at 2019-05-06

はじめに

FirebaseのCloud Functionsを使ってNode.js(TypeScript)のETH testnet用トークン配布システムを作ります:fire:

事前準備

まず、何らかの方法でETHのアドレスと秘密鍵を用意してください
あらかじめtestnet(ここではrinkeby)のETHを入れておきましょう

コードから作成する方法

セットアップ

firebaseプロジェクトをこちらから作ってください

firebaseのCLI入れてない方は入れましょう

npm install -g firebase-tools
mkdir eth-faucet
cd eth-faucet
firebase login
firebase init

ここでFunctionsを選択
スクリーンショット 2019-05-06 14.42.37.png

その後「Select a default Firebase project for this directory:」と言われるので先ほど作ったFirebaseのプロジェクトを選択

※反映されてない場合は「don't setup a default project」を選択し、あとでfirebase use --add [project-id]とすればOK

スクリーンショット 2019-05-06 14.47.13.png

TypeScriptを選択しTSLintも導入してもらいましょう

最後にFirebase Consoleでプロジェクトの課金設定をBlazeにします

理由は無料版だとfirebase関連以外の外部パッケージが使えないからです

スクリーンショット 2019-05-06 14.55.08.png

スクリーンショット 2019-05-06 14.55.21.png

作っていく

Express, web3, ethreumjs-txを導入します
ExpressはNode.jsの最小限なフレームワークです
Expressの型定義ファイルもインストールします

cd functions
npm install --save express web3 ethereumjs-tx
npm install --save-dev @types/express

次にsrc/index.tsを編集します
全体のコードはこちらです

src/index.ts

import * as functions from 'firebase-functions';
import * as Express from 'express';

const Web3 = require('web3');
const Tx = require('ethereumjs-tx');

const app = Express();

const networks  = {
  main: 'wss://mainnet.infura.io/ws/v3/',
  ropsten: 'wss://ropsten.infura.io/ws/v3/',
  kovan: 'wss://kovan.infura.io/ws/v3/',
  rinkeby: 'wss://rinkeby.infura.io/ws/v3/'
};

// InfuraのAPI-KEY(作る)
const apiKey = 'YOUR-API-KEY';
// テストネット(ここではrinkebyを選択)
const network = networks.rinkeby;

// rinkebyネットワークに接続する処理
const getWeb3 = () => {
  const provider = network + apiKey;
  const web3 = new Web3(provider);
  return web3;
}

app.get('/:address', async(req:Express.Request, res: Express.Response) => {
    try {
        const from = '用意したETHアカウントのアドレス';
        const to = req.params.address;
        const privateKey = '用意したETHアカウントの秘密鍵';
        const amount = 0.01  // faucetとして配布したいETHの量
        const web3 = getWeb3();

        const value = web3.utils.toWei(amount.toString(), 'ether');

        const gasParams = {
            from: from,
            to: to,
            value: value,
        }
        const gasLimit = await web3.eth.estimateGas(gasParams);
        const gasPrice = await web3.eth.getGasPrice();
        const count = await web3.eth.getTransactionCount(from);

        const data = null;
        const id = await web3.eth.net.getId();


        const params = {
            nonce: web3.utils.numberToHex(count),
            gasPrice: web3.utils.numberToHex(gasPrice),
            gasLimit: web3.utils.numberToHex(gasLimit),
            to: to,
            from: from,
            value: web3.utils.numberToHex(value),
            data: data,
            chainId: id
        }
        //Transaction作成
        const tx = new Tx(params);
        const _privateKey = Buffer.from(privateKey.slice(2), 'hex');

        //Transactionに秘密鍵で署名
        tx.sign(_privateKey);
        const rawTx = '0x' + tx.serialize().toString('hex');
        const result = await web3.eth.sendSignedTransaction(rawTx);

        //Transactionを送信した結果がtrueならresponseを返す
        if(result.status == true) {
            res.send('送金が完了しました\n')
        }
    }
    catch(error) {
        res.status(500).send(error)
    }
})

exports.app = functions.https.onRequest(app);

その後以下を実行

firebase deploy --only functions:app

そしてcurlでルートにETHの送り先アドレスを込めて叩く

curl https://us-central1-<project-id>.cloudfunctions.net/app/<送り先のアドレス>

コンソール上で送金が完了しましたと出ればOK

この時、Error: could not handle the requestのようにtimeout errorが出ることがありますがEtherscanでみるときちんと送金はされています

3
1
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
3
1