1
0

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 1 year has passed since last update.

NTTデータ先端技術株式会社 デジタルソリューション事業部Advent Calendar 2023

Day 20

Web3Signerを使ってトランザクション署名してみた

Last updated at Posted at 2023-12-19

はじめに

私が最近関わったブロックチェーン案件で、「トランザクション署名に使う秘密鍵をセキュアに保管/利用する方法」を調査する機会がありました。
この調査したものの一つにWeb3Signerという署名ツールがあり、このツールに関しては簡単なトランザクション署名の動作確認まで行いました。
その動作確認内容を、本記事ではメモしておこうと思っています。
(一応、最後にまとめと感想も書いています)

Web3Signerとは

Web3Signerとは、一般にVaultと呼ばれる外部サービスまたはディスクに保存された秘密鍵を使って、データに署名できるツール1です。Consensysによって提供されています。
Vaultと呼ばれる外部サービスとは、Azure Key VaultやAWS KMSなどの鍵管理サービス2のことです。

また、Web3Signerによる署名は、以下の2つのレイヤーで利用できます。

  • 実行レイヤー(eth1): EOAによるトランザクションへの署名
  • コンセンサスレイヤー(eth2): バリデータによるデータへの署名

以下は実行レイヤー(eth1)でのトランザクション署名~トランザクション送信のイメージ図です。
(コンセンサスレイヤー(eth2)に関しては、私が理解できていないので省略します!)

image.png

やったことの概要

まず、基盤部分の準備として、Web3Signerとブロックチェーンネットワークを構築します。
Web3Signerに対しては、秘密鍵情報として暗号化していない平文ファイルを用意します。
ブロックチェーンネットワークには、Hardhatに組み込まれた開発用のEthereumネットワークを用意します。

基盤部分が準備できたら、Web3Signerに対してトランザクション署名をしてもらい、署名済みのトランザクションをブロックチェーンネットワークに送信します。
そして、このトランザクション送信がちゃんと処理されるか確認します。

image.png

動作環境

以下の環境で動かしてみました。
Java JDKは、Web3Signerを動かす上で必要です。(バージョンは17以上)
Nodejsは、Hardhatが動けば何でもいいです。

# 項目 バージョン
1 OS Ubuntu 20.04 (WSL)
2 Java JDK 21.0.1 (17より上ならOK)
3 Nodejs, npm 20.9.0, 10.1.0 (Hardhatが動けば何でもOK)
4 Web3Signer 23.11.0
5 Hardhat 2.19.2

詳細な手順

以下から記載する手順は、作業ディレクトリを作ってその配下で行います。
ディレクトリ名は何でもいいです。

mkdir web3signer-test
cd web3signer-test

必要なパッケージのインストール

まず、Web3SignerとHardhatをインストールします。
(Java JDK,Nodejs,npmはインストール済みの想定です)

Web3Signerのインストール

以下を実行して、ビルド済みのWeb3Signerをダウンロードし、作業ディレクトリに展開します。

wget https://artifacts.consensys.net/public/web3signer/raw/names/web3signer.tar.gz/versions/23.11.0/web3signer-23.11.0.tar.gz
tar xvzf web3signer-23.11.0.tar.gz

Hardhatのインストール

以下を実行して、Hardhatをインストールします。

npm install hardhat

ブロックチェーンネットワークの準備

今回は簡単のため、ブロックチェーンネットワークとしてHardhat Networkを使います。
Hardhat Networkとは、Hardhatに組み込まれ、開発用に設計されたローカルのEthereumネットワークです。

Hardhat Networkの起動

まず以下を実行します。

npx hardhat init

実行後、以下の画面がでるので、Create an empty hardhat.config.jsを選択します。
image.png
その後、以下を実行しHardhat Networkを起動します。
Hardhat Networkは、起動時に10000 ETHを持ったEOAを20個作ってくれます。今回の手順では、その内の2つのEOAを使います。

# Hardhat Networkの起動
npx hardhat node

# 以下の2つのEOAを使います
Account #18: 0xdD2FD4581271e230360230F9337D5c0430Bf44C0 (10000 ETH)
Private Key: 0xde9be858da4a475276426320d5e9262ecfc3ba460bfac56360bfa6c4c28b4ee0

Account #19: 0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199 (10000 ETH)
Private Key: 0xdf57089febbacf7ba0bc227dafbffa9fc08a93fdc68e1e42411a14efcf23656e

Web3Signerの起動

Web3Signerは、保管する鍵を.yaml形式の「key configurationファイル」で保持します。
そのため、保管する鍵情報を「key configurationファイル」として作成した後に、Web3Signerを起動します。

key configurationファイルの作成

今回は簡単のため、key configurationファイルを、暗号化していない平文ファイル(Web3Signerの定義だとfile-raw形式)で作成します。

まず、keysディレクトリを作成します。

mkdir keys

その後、keysディレクトリ配下に、以下のファイルを配置します。

  • keys19.yaml ※名前はこの通りである必要はありませんが、.yaml形式にします
    # Account #19
    type: "file-raw"
    keyType: "SECP256K1"
    privateKey: "0xdf57089febbacf7ba0bc227dafbffa9fc08a93fdc68e1e42411a14efcf23656e"
    

実際にシステムを組む際は、鍵はAzure Key VaultやAWS KMSなどに保管し、それとWeb3Signerを連携させる方が良いと思います。
詳しく知りたい場合は、以下から調べてみてください。
https://docs.web3signer.consensys.io/how-to/store-keys

起動コマンドの実行

以下を実行してWeb3Signerを起動します。

./web3signer-23.11.0/bin/web3signer --key-store-path=keys eth1 --chain-id=31337

以下は、各オプションの説明です。

  • --key-store-path
    「key configurationファイル」を配置したディレクトリへのパスを指定します。
  • eth1
    実行レイヤー(eth1)でWeb3Signerを起動します。eth2を指定するととコンセンサスレイヤー(eth2)での起動になります。eth1eth2で、使用可能なサブコマンドが変わります。
    • --chain-id
      実行レイヤー(eth1)用のサブコマンドです。
      ブロックチェーンネットワークのchainIdを指定します。Hardhat NetworkのデフォルトchainIdである31337を指定しています。

Web3Signerによるトランザクション署名

基盤部分が用意できたら、Web3Signerでトランザクションを署名します。
ここで署名するトランザクションは、上述のAccount#19からAccount#18へ、ETH送金を行うトランザクションです。
以下を実行し、eth_signTransactionで送金トランザクションに署名します。

# トランザクションの署名リクエスト(To: Web3Signerのポート9000)
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_signTransaction","params":[{"from": "0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199","to": "0xdD2FD4581271e230360230F9337D5c0430Bf44C0","gas": "0x7600","gasPrice": "0x9184e72a000","value": "0x9184e72a", "nonce":"0x0"}], "id":1}' http://127.0.0.1:9000

実行後、以下のような応答が返ってきます。
resultの項目に入っているのが署名済みのトランザクションです。これをブロックチェーンネットワークに送信します。

# 署名済みのトランザクションが返ってくる
{"jsonrpc":"2.0","id":1,"result":"0xf86b808609184e72a00082760094dd2fd4581271e230360230f9337d5c0430bf44c0849184e72a8082f4f5a0ea487bb8f9fb8413e1f7f45e1e5845ab0a61005414e4828ab2adf5c9d743d57ba06ef102661655699748bca4fe210c50dc459e7be1f25e4dde2624044024c53de2"}

署名したトランザクションの送信

Web3Signerで署名したトランザクションをブロックチェーンネットワークに送信します。
以下を実行し、eth_sendRawTransactionで上記の署名済みトランザクションをブロックチェーンネットワークへ送信します。
(paramsの項目に上記の署名済みトランザクションが入っています。)

# トランザクション送信リクエスト(To: Hardhat Networkノードのポート8545)
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0xf86b808609184e72a00082760094dd2fd4581271e230360230f9337d5c0430bf44c0849184e72a8082f4f5a0ea487bb8f9fb8413e1f7f45e1e5845ab0a61005414e4828ab2adf5c9d743d57ba06ef102661655699748bca4fe210c50dc459e7be1f25e4dde2624044024c53de2"],"id":1}' http://127.0.0.1:8545

送信成功すると、Hardhat Networkを起動しているターミナルで以下が表示されます。
image.png

(補足) eth_sendTransaction(署名&送信)の使い方

補足ですが、eth_sendTransactionを使うと、上記の署名(eth_signTransaction)と送信(eth_sendRawTransaction)をまとめて行うことができます。
署名と送信の2ステップに分ける必要が無く、簡便にトランザクションを送りたい場合は、eth_sendTransactionを使うことで1リクエストで2ステップを行えます。
(反対に、署名と送信の2ステップに分けると、シーケンスを詳細にコントロールできるという利点があるので、2ステップに分ける分けないの使い分けができるという点が便利なポイントです。)

image.png

ただ、eth_sendTransactionを使うためには、Web3Signerに対して、ブロックチェーンノードへのdownstream設定をする必要があります。
以下を実行してWeb3Signerを起動すると、Web3Signerがブロックチェーンノード(ポート番号8545)へアクセスしてくれるようになります。

./web3signer-23.11.0/bin/web3signer --key-store-path=keys eth1 --chain-id=31337 --downstream-http-port=8545

downstreamの設定をすると、eth_sendTransactionを使えるようになります。
以下を実行すると、一度でトランザクションの署名から送信まで行ってくれます。

# トランザクションの署名&送信リクエスト(To: Web3Signerのポート9000)
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"from": "0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199","to": "0xdD2FD4581271e230360230F9337D5c0430Bf44C0","gas": "0x7600","gasPrice": "0x9184e72a000","value": "0x9184e72a"}], "id":1}' http://127.0.0.1:9000

まとめと感想

本記事ではWeb3Signerの紹介をし、簡単な構成と簡単な鍵管理方法でWeb3Signerを起動してみました。
そして、Web3Signerの実行レイヤー(eth1)での署名機能を使ったトランザクション署名&送信を試してみて、正常にトランザクション処理がされることを確認しました。

今回Web3Signerを触ってみて、Web3Signerの起動方法やAPIの使い方が分かったのは良かったです。
また、Web3Signerに使ってもらう秘密鍵情報を、暗号化していない平文ファイルで用意できるので、テスト環境の構築や今回のような簡易的な評価なら簡単にできるのは便利だと感じました。

ただ、Web3Signerを使う上で重要なポイントは「秘密鍵をセキュアに保管/利用する方法」だと思いますので、既存の鍵管理サービス(Azure Key Vault, AWS KMSなど)との連携方法をさらに調査しないといけないなと思いました。
また、コンセンサスレイヤー(eth2)の署名に関しても、バリデータノードのコンセンサス関連の処理について勉強しながら理解していきたいと思いました。

参考

  1. Consensysが提供する署名ツールには、他にも以下があるようですが、今はWeb3Signerがメインで開発されているようです。

  2. Web3Signerと連携できる鍵管理サービスについては、こちらを参照してください。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?