[ERC4527] QRコードを使用してネットワークから隔離された署名デバイスと閲覧のみ可能なウォレットを接続する仕組みを理解しよう！

# はじめに

『DApps開発入門』という本や色々記事を書いているかるでねです。

https://amzn.asia/d/gxvJ0Pw

今回は、ネットワークから完全に隔離された署名デバイスと、通信可能な閲覧のみ可能なウォレットをQRコードを使用して安全にデータのやり取りを行う仕組みを提案している**ERC4527**についてまとめていきます！

:::note info
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-4527

他にも様々なEIPについてまとめています。

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

# 概要

**ERC4527**は、オフライン署名デバイス（ハードウェアウォレットや通信を切ったスマートフォンなど）と閲覧のみ可能なウォレットとの間で、QRコードを使って安全にデータをやり取りするための手順とプロトコルを定める提案をしています。
閲覧のみ可能なウォレットが署名対象データを準備し、オフライン署名デバイスがそれを読み取って署名を生成するという一連の流れを標準化しています。

# 動機

秘密鍵を完全にネットワークから隔離して管理したいユーザーが増えており、オフライン署名デバイスを用いるケースが一般化しています。
しかし現状では、以下の複数のデータ転送方法が混在し、手順やエンコード形式も統一されていません。QRコード方式には次の利点があります。

- QRコード
- USB接続
- Bluetooth
- ファイル転送

QRコード方式には次の利点があります。

- 透明性と安全性

QRコードは簡単に内容をデコードでき、ユーザーが署名内容を目視で確認できます。

- 高い互換性

ブラウザやOSの更新による影響を受けにくく、デバイス間で幅広く利用できます。

- モバイルでの優れたユーザー体験

ケーブルやペアリング不要で、スマートフォンでも扱いやすいです。

- 攻撃面の縮小

USBやBluetoothに比べ、攻撃対象領域が小さくなります。

これらの理由から、QRコードはオフライン署名に適した手段といえます。
しかし従来は現代的な標準が存在しませんでした。
**ERC4527**では、オフライン署名の手順とQRコードのデータ形式を統一することで互換性と安全性を高め、ユーザー体験を向上させることを目的としています。

# 仕様

## 用語

- オフライン署名デバイス  
  ネットワーク接続を持たず、ユーザーの秘密鍵を保持する端末やアプリです。  

- 閲覧のみ可能なウォレット  
  ネットワークに接続してEthereumブロックチェーンとやり取りできるウォレットです。  

## プロセス

1. オフライン署名デバイスが公開鍵情報を QR コードで閲覧のみ可能なウォレットへ送信し、ウォレットはアドレス生成や残高同期を行います。  
2. 閲覧のみ可能なウォレットは未署名データ（トランザクションや**EIP712**型データなど）を作成し、QR コードでオフライン署名デバイスへ送信します。  
3. オフライン署名デバイスがデータに署名し、署名結果をQRコードで閲覧のみ可能なウォレットへ返します。  
4. 閲覧のみ可能なウォレットは署名を受け取り、トランザクションを組み立ててブロードキャストします。  

:::note info
**EIP712**については以下の記事を参考にしてください。
:::

https://qiita.com/cardene/items/f54bc85cb66de5a54257

## データ伝送プロトコル

データ容量制限を超える場合に備え、アニメーションQRコード（複数フレーム）を使用します。  
エンコード方式は BlockchainCommons が定義する**UR (Uniform Resources)**を採用して**ERC4527**で拡張します。  
バイナリ表現には **CBOR (Concise Binary Object Representation)**、構造記述には **CDDL (Concise Data Definition Language)** を用います。  

## 閲覧のみ可能なウォレットのセットアップ

オフライン署名デバイスは拡張公開鍵 (Extended Public Key) と導出パスを提供します。  
UR では`crypto-hdkey`型で公開鍵を、導出パスを`crypto-keypath`で表現します。  

### キーパスの CDDL

```js
crypto-keypath = {
    components: [path-component],       ; 空の場合は source-fingerprint 必須
    ? source-fingerprint: uint32 .ne 0  ; 祖先キーまたはマスターキーの指紋
    ? depth: uint8                      ; 派生段数
}
path-component = (
    child-index / child-index-range / child-index-wildcard-range,
    is-hardened
)
uint32 = uint .size 4
uint31 = uint32 .lt 2147483648          ; 0x80000000
child-index = uint31
child-index-range = [child-index, child-index]
child-index-wildcard-range = []
is-hardened = bool
components = 1
source-fingerprint = 2
depth = 3
```

### 拡張公開鍵の CDDL

```js
hd-key = {
    derived-key
}
derived-key = (
    key-data: key-data-bytes,
    ? chain-code: chain-code-bytes,
    ? origin: #6.304(crypto-keypath),
    ? name: text,
    ? source: text
)
key-data = 3
chain-code = 4
origin = 6
name = 9
source = 10

uint8 = uint .size 1
key-data-bytes = bytes .size 33
chain-code-bytes = bytes .size 32
```

チェーンコードがあれば子鍵を導出できます。
無い場合は単独鍵として扱われます。
複数公開鍵のみを渡したい場合は`crypto-account`を利用します。  

## 未署名データ送信

閲覧のみ可能なウォレットからオフライン署名デバイスへ未署名データを渡すために、新しいUR型`eth-sign-request`を定義します。  

### `eth-sign-request`のCDDL

```js
sign-data-type = {
    type: int .default 1               ; 1: unsigned Tx, 2: EIP-712, 3: raw bytes, 4: typed Tx
}

eth-sign-request = (
    sign-data: sign-data-bytes,
    data-type: #3.401(sign-data-type),
    chain-id: int .default 1,
    derivation-path: #5.304(crypto-keypath),
    ?request-id: uuid,
    ?address: eth-address-bytes,
    ?origin: text
)
request-id = 1
sign-data = 2
data-type = 3
chain-id = 4
derivation-path = 5
address = 6
origin = 7

eth-address-bytes = bytes .size 20
sign-data-bytes = bytes                ; Tx は RLP、EIP-712 は JSON 文字列の bytes
```

## 署名返却

オフライン署名デバイスは署名を`eth-signature`としてQRコードで返送します。  
### `eth-signature`のCDDL

```js
eth-signature = (
    request-id: uuid,
    signature: eth-signature-bytes,
    ?origin: text
)

request-id = 1
signature = 2
origin = 3

eth-signature-bytes = bytes .size 65   ; r, s, v を連結した 65 バイト
```

この署名をもとに閲覧のみ可能なウォレットがトランザクションを完成させ、ネットワークへ送信します。

# 補足

## QRコード伝送の堅牢な基盤を提供

UR はアルファベット・数字モードを使用して効率的にデータをエンコードします。  
全てのパートにメッセージ全体のCRC32チェックサムを含めるため、複数フレームの再構成時に整合性を確認できます。  
Fountain Code を採用し、可変長データでも最小限かつ柔軟なパート数で送信できるため、受信側の復元が容易です。  

## 既存型の活用と拡張性

UR には `crypto-keypath` や `crypto-hdkey` など既存の型があり、新しい `eth-sign-request` や `eth-signature` といった型も追加しやすい設計です。  

## 活発なエアギャップウォレットコミュニティ

URには継続的に改善を行う活発なエアギャップウォレットコミュニティが存在し、標準の進化が期待できます。

# 互換性

互換性の問題はありません。

# セキュリティ

## データの完全表示とユーザー確認  

オフライン署名デバイスは、受信した `eth-sign-request` を必ずデコードし、その内容を署名前にユーザーへ表示します。
ユーザーは表示されたデータを確認し、意図した内容であることを承認してから署名操作を行います。

## アドレスフィールドの推奨と検証  

`eth-sign-request` にはアドレスフィールドを含めることが推奨されます。
オフライン署名デバイスは、このアドレスが自分の署名用キーに対応するアドレスと一致しているかを検証します。
一致しない場合は署名を拒否し、不正な要求による誤署名を防ぎます。

# 引用

Aaron Chen (@aaronisme), Sora Lee (@soralit), ligi (@ligi), Dan Miller (@danjm), AndreasGassmann (@andreasgassmann), xardass (@xardass), Lixin Liu (@BitcoinLixin), "ERC-4527: QR Code transmission protocol for wallets [DRAFT]," Ethereum Improvement Proposals, no. 4527, December 2021. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-4527.

# 最後に

今回は「ネットワークから完全に隔離された署名デバイスと、通信可能な閲覧のみ可能なウォレットをQコードを使用して安全にデータのやり取りを行う仕組みを提案している**ERC4527**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

他の媒体でも情報発信しているのでぜひ他も見ていってください！

https://chaldene.net/

https://zenn.dev/heku

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4