[ERC5570] レシートをNFTとして発行する仕組みを理解しよう！

# はじめに

初めまして。
**CryptoGames**というブロックチェーンゲーム企業でエンジニアをしている **cardene（かるでね）** です！
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

https://cryptogames.co.jp/

代表的なゲームは**クリプトスペルズ**というブロックチェーンゲームです。

https://cryptospells.jp/

今回は、商品を購入したレシートをNFTのメタデータに書きこんで、ブロックチェーン上に書き込むことができる**ERC5570**についてまとめていきます！

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

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

# 概要

このERC提案は、取引のデジタルレシートに関する標準スキーマを提案しています。
デジタルレシート非代替トークン（Digital Receipt Non-Fungible Tokens）は、顧客が店舗で購入を行った際にベンダーが発行するもので、記録のために必要な取引詳細を含んでいます。
これは、一意のトークンの管理と所有を可能にする**ERC721**を拡張しています。

:::note info
ベンターとは、商品やサービスを提供する事業者や販売業者のことです。
この提案では、顧客が商品を購入する際に提供されるレシートを発行する事業者を指しています。
ベンダーは、取引の際に必要な情報を含むデジタルレシートを発行して、顧客や取引の記録を管理する役割を果たします。
:::

# 動機
オンライン小売業者からの購入には、電子メールや物理的な手段で顧客に提供されるレシートが含まれています。
これらのレシートは多くの理由で重要ですが、アナログ形式で提供されており、金融システムで解析するのが難しいです。
デジタルレシートは、既にデジタル化されたポイントオブセールシステムからデジタルな形式で提供されるべきですが、これが実現されていません。
したがって、不要なデータ入力や不便なレシートスキャンアプリの使用が必要な、「**冗長なデジタル -> アナログ -> デジタル**」のプロセスが残っています。

:::note info
「**冗長なデジタル -> アナログ -> デジタル**」についての補足です。
顧客がオンライン小売業者から商品を購入した際に、以下のような手順を踏む必要がある状況を指しています。

1. **デジタルステップ**（デジタル -> アナログ）
   - 顧客がオンラインストアで商品を購入し、取引が完了すると、通常はデジタルな手段で領収書やレシートが提供されます。
   - これは電子メールで送られることが一般的です。

2. **アナログステップ**（アナログ -> デジタル）：
   - しかし、この領収書やレシートはアナログ形式で提供されており、紙の形で送付されることがあります。
   - 顧客はこれらのアナログなレシートを手で入力してデジタルなフォーマットに変換する必要があります。
   - または、不便なレシートスキャンアプリを使用して紙のレシートをスキャンし、デジタルな形式に変換する必要があります。

3. **デジタルステップ**（デジタル -> デジタル）：
   - 顧客は手動で入力したり、スキャンした情報をデジタルなシステムにアップロードすることで、自身のデジタルな記録システムにデータを取り込むことができます。

このプロセスは、デジタルな取引がアナログなフォーマットに変換され、再びデジタルな形式に戻されるため、無駄な手間や時間を必要とします。
この過程は手作業が多く、誤りや漏れが生じる可能性もあります。
提案されているデジタルレシート非代替トークン（Digital Receipt Non-Fungible Tokens）のアイデアは、このプロセスを効率的に改善し、デジタルな取引の詳細情報を直接デジタルな形式で管理できるようにすることです。
これによって、取引の透明性と追跡性が向上し、人間エラーが減少します。
:::

デジタルレシートは比較的シンプルで、JSONや他の構造化された形式に解析できるスキーマで指定できます。
さらに、ベンダーの秘密鍵を使用してレシートにデジタル署名することで、レシートの妥当性を証明できます。

Ethereumが拡張されるにつれて、エンドユーザーに、法定通貨取引で既に利用可能な機能（レシートなど）を提供するためのツールが開発される必要があります。
NFTは、チェーン上の購入とその取引詳細をトランザクションの状態更新を介して直接リンクさせるユニークな機会を提供します。
もしトランザクションを資金の提供者と商品の提供者と考えるならば、現実の状態にはトランザクションの2つの側面が含まれます。
取引は、一方の参加者からもう一方の参加者に対して資金（通常はお金）を提供し、その代わりに商品やサービスを提供するプロセスです。
購入者がお金を支払って商品を購入する場合、お金（資金）の所有権が購入者から販売者に移動します。
同時に、商品の所有権も販売者から購入者に移動します。
この取引のプロセスをブロックチェーン上で透明に表現するため、NFTレシート（デジタルレシート非代替トークン）が提案されています。
NFTレシートは、商品の所有権の変化をブロックチェーン上で一意に識別可能なトークンとして表現します。
具体的には、商品を購入した際にNFTレシートが発行され、このNFTが取引の一部として商品の所有権の変化をブロックチェーン上で記録します。

これによって、ブロックチェーン上のトランザクションの状態が現実世界で起きている取引の変化と一致するようになります。
資金の移動や商品の所有権の変化が透明かつ不変な方法でトランザクションとして表現されるため、取引の透明性と信頼性が向上します。
NFTレシートは、このような商品の所有権の変化を正確に記録し、ブロックチェーン上の取引の状態を現実の取引に合わせるための重要な役割を果たします。

**トランザクション状態とNFTレシートの利点**
ブロックチェーン上でのトランザクション状態とNFTレシートの直接的なリンクは、大きな利便性をもたらします。
これにより、取引の詳細情報がすぐにアクセス可能な形で提供されます。
他の方法、たとえばオフチェーンでのレシート保管や別のスマートコントラクトを通じたレシートの配布では、このリンクが失われ、ユーザーが取引詳細を手動で探す必要が生じます。
NFTレシートを使用することで、ウォレット内でトランザクションをクリックするだけで関連するレシートにアクセスできるため、エンドユーザーの利便性が向上します。

**デジタルレシートの概念的な拡張性**
NFTとしてのデジタルレシートは、商品の所有権の変化を捉えるだけでなく、さまざまな他の情報も概念的に含むことができます。
例えば、商品のシリアル番号や配送トラッキング情報など、顧客にとって重要な詳細情報をレシートに追加することができます。
これにより、トランザクションの透明性や詳細性が向上し、顧客が購入した商品に関する情報を一元管理できるようになります。

**財務システムの自動化とブロックチェーンの役割**
紙のレシートを人間が追跡する方法は非効率で時代遅れであり、ヒューマンエラーが発生する可能性があります。
しかし、ブロックチェーン上のNFTを使用することで、取引詳細を確実に、正確に、かつ自動的に追跡できるようになります。
これは財務システムの自動化の一環として大きな進歩です。
NFTを活用することで、トランザクションの履歴や詳細をデジタルな形式で記録・追跡できるため、取引の透明性が向上し、管理や監査が容易になります。
ブロックチェーン上のNFTは、これらの財務システムの効率化と進化に向けた重要な手段となります。

# 仕様

**トランザクションの流れ**
1. 顧客がオンライン小売業者から商品を購入します。
   - 顧客がウェブサイトなどを通じて商品を選び、購入手続きを進めます。
2. 購入手続きを進めると、顧客にはNFTを作成するオプションが提供されます。
   - 購入手続きが進む過程で、顧客にはデジタルレシート非代替トークン（NFT）を作成するオプションが提示されます。
   - このNFTは、後にトランザクションの詳細情報を保持するためのデジタルなトークンとして機能します。
3. スマートコントラクトは顧客にデジタルレシート非代替トークン（NFT）を提供します。
   - 購入手続きが完了すると、スマートコントラクトは顧客にNFTを発行します。
   - このNFTは、デジタルレシートに関連する情報を保持するための特別なトークンであり、ブロックチェーン上に記録されます。
4. 販売業者は注文を履行する際に、以前に作成したNFTに、以下のJSONスキーマで指定されたデジタルレシートをメタデータとしてアップロードします。
   - 販売業者が顧客の注文を準備し、商品を発送する際に、デジタルレシートを特定のJSONスキーマに基づいて作成します。
   - そして、このデジタルレシートをブロックチェーン上に作成されたNFTのメタデータとしてアップロードします。
   - これにより、トランザクションの詳細情報がNFTに関連付けられ、ブロックチェーン上で確認できるようになります。

このようにして、顧客がオンライン小売業者から商品を購入する際に、NFTを介してトランザクションの詳細情報が効率的に管理され、透明性が確保される仕組みが構築されます。

**デジタルレシート JSON スキーマ**
デジタルレシートJSONスキーマは以下の2つのパートに分かれます。

**1. ルートスキーマ（Root Schema）：**

![30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570269/c248b8c7-01b5-4558-9bc1-86ae43fae2a5.png)

ルートスキーマは、デジタルレシートの高レベルの詳細情報を含む部分です。
これには、取引の日付や販売業者（ベンダー）などの基本的な情報が含まれます。
例えば、いつ取引が行われたかや、どの販売業者から商品を購入したかなどがルートスキーマに含まれます。
これらの情報は、デジタルレシートの全体像を提供するために使用されます。

**2. レシートの繰り返し項目を記述するスキーマ**

![31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570269/09f77f7f-dcd7-7df3-ee59-acd262ead290.png)

デジタルレシートには、1つ以上の項目が含まれる場合があります。
例えば、複数の商品やサービスが含まれる場合、それぞれの項目に対する詳細情報が必要です。
このため、別のスキーマが用意されており、これによってレシート内の各項目に関する情報が記述されます。
このスキーマは、繰り返し項目の詳細を効率的に表現するためのものです。

繰り返し項目を記述するスキーマは、レシート内の個々の項目に関する情報を包括的に記述します
例えば、商品の名前、数量、価格などが含まれます。
このスキーマによって、レシート内の複数の項目を組織化し、それぞれの項目に関する情報を明確に表現することが可能となります。

このJSONスキーマは、デジタルレシートの全体的な構造を提供し、ルートスキーマと繰り返し項目を記述するスキーマの組み合わせによって、取引の詳細情報を効果的かつ体系的に記録・管理できるようになっています。

これによって、顧客がオンライン小売業者から商品を購入した際に、トランザクションの詳細情報を含むNFTが作成されます。
販売業者はこのNFTにデジタルレシートをアップロードし、トランザクションの詳細情報をブロックチェーン上で管理・保持できるようになります。
これによって、トランザクションの透明性が向上し、顧客や販売業者の両方が簡単に取引詳細を追跡できる環境が提供されます。

## ルートスキーマ

```json
{
  "id": "receipt.json#",
  "description": "Receipt Schema for Digital Receipt Non-Fungible Tokens",
  "type": "object",
  "required": ["name", "description", "image", "receipt"],
  "properties": {
    "name": {
      "title": "Name",
      "description": "Identifies the token as a digital receipt",
      "type": "string"
    },
    "description": {
      "title": "Description",
      "description": "Brief description of a digital receipt",
      "type": "string"
    },
    "receipt": {
      "title": "Receipt",
      "description": "Details of the receipt",
      "type": "object",
      "required": ["id", "date", "vendor", "items"],
      "properties": {
        "id": {
          "title": "ID",
          "description": "Unique ID for the receipt generated by the vendor",
          "type": "string"
        },
        "date": {
          "title": "Date",
          "description": "Date Receipt Issued",
          "type": "string",
          "format": "date"
        },
        "vendor": {
          "title": "Vendor",
          "description": "Details of the entity issuing the receipt",
          "type": "object",
          "required": ["name", "website"],
          "properties": {
            "name": {
              "title": "Name",
              "description": "Name of the vendor. E.g. Acme Corp",
              "type": "string"
            },
            "logo": {
              "title": "Logo",
              "description": "URL of the issuer's logo",
              "type": "string",
              "format": "uri"
            },
            "address": {
              "title": "Address",
              "description": "List of strings comprising the address of the issuer",
              "type": "array",
              "items": { "type": "string" },
              "minItems": 2,
              "maxItems": 6
            },
            "website": {
              "title": "Website",
              "description": "URL of the issuer's website",
              "type": "string",
              "format": "uri"
            },
            "contact": {
              "title": "Contact Details",
              "description": "Details of the person to contact",
              "type": "object",
              "required": [],
              "properties": {
                "name": {
                  "title": "Name",
                  "description": "Name of the contact person",
                  "type": "string"
                },
                "position": {
                  "title": "Position",
                  "description": "Position / Role of the contact person",
                  "type": "string"
                },
                "tel": {
                  "title": "Telephone Number",
                  "description": "Telephone number of the contact person",
                  "type": "string"
                },
                "email": {
                  "title": "Email",
                  "description": "Email of the contact person",
                  "type": "string",
                  "format": "email"
                },
                "address": {
                  "title": "Address",
                  "description": "List of strings comprising the address of the contact person",
                  "type": "array",
                  "items": { "type": "string" },
                  "minItems": 2,
                  "maxItems": 6
                }
              }
            }
          }
        },
        "items": {
          "title": "Items",
          "description": "Items included into the receipt",
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "$ref": "item.json#"
          }
        },
        "comments": {
          "title": "Comments",
          "description": "Any messages/comments the issuer wishes to convey to the customer",
          "type": "string"
        }
      }
    },
    "image": {
      "title": "Image",
      "description": "Viewable/Printable Image of the Digital Receipt",
      "type": "string"
    },
    "signature": {
      "title": "Signature",
      "description": "Digital signature by the vendor of receipts data",
      "type": "string"
    },
    "extra": {
      "title": "Extra",
      "description": "Extra information about the business/receipt as needed",
      "type": "string"
    }
  }
}
```

このJSONスキーマは、デジタルレシートの詳細情報を定義するためのものです。
以下に、スキーマの各部分の説明を示します。

- **id**
    - スキーマの識別子です。
- **description**
    - デジタルレシート非代替トークンのためのスキーマの説明です。
- **type**
    - オブジェクトのタイプを指定します。

### ルートスキーマの必須プロパティ
- **name**
    - デジタルレシートを識別するための名前です。
- **description**
    - デジタルレシートの簡単な説明です。
- **image**
    - デジタルレシートの表示可/印刷可能な画像へのURLです。
- **receipt**
    - デジタルレシートの詳細情報を含むオブジェクトです。

### レシートの詳細情報を定義するためのプロパティ
- **id**
    - 販売業者によって生成されるレシートのユニークなIDです。
- **date**
    - レシートが発行された日付です。
- **vendor**
    - レシートを発行した販売業者の詳細情報です。
- **items**
    - レシートに含まれる項目の配列です。各項目は「`item.json#`」として参照される別のスキーマに準拠します。
- **comments**: 販売業者が顧客に伝えたいメッセージやコメントです。

### 販売業者の詳細情報を定義するためのプロパティ
- **name**
    - 販売業者の名前です。
- **logo**
    - 販売業者のロゴのURLです。
- **address**
    - 販売業者の住所の配列です。
- **website**
    - 販売業者のウェブサイトのURLです。
- **contact**
    - 販売業者の連絡先情報です。名前、役職、電話番号、メールアドレス、住所などが含まれます。

### その他のプロパティ
- **signature**
    - レシートデータの販売業者によるデジタル署名です。
- **extra**
    - ビジネスやレシートに関する追加情報が含まれるプロパティです。

## ラインアイテムスキーマ

```json
{
  "type": "object",
  "id": "item.json#",
  "required": ["id", "title", "date", "amount", "tax", "quantity"],
  "properties": {
    "id": {
      "title": "ID",
      "description": "Unique identifier of the goods or service",
      "type": "string"
    },
    "title": {
      "title": "Title",
      "description": "Title of the goods or service",
      "type": "string"
    },
    "description": {
      "title": "Description",
      "description": "Description of the goods or service",
      "type": "string"
    },
    "link": {
      "title": "Link",
      "description": "URL link to the web page for the product or sevice",
      "type": "string",
      "format": "uri"
    },
    "contract": {
      "title": "Contract",
      "description": "URL link or hash to an external contract for this product or service",
      "type": "string"
    },
    "serial_number": {
      "title": "Serial Number",
      "description": "Serial number of the item",
      "type": "string"
    },
    "date": {
      "title": "Supply Date",
      "description": "The date the goods or service were provided",
      "type": "string",
      "format": "date"
    },
    "amount": {
      "title": "Unit Price",
      "description": "Unit Price per item (excluding tax)",
      "type": "number"
    },
    "tax": {
      "title": "Tax",
      "description": "Amount of tax charged for unit",
      "type": "array",
      "items": {
        "type": "object",
        "required": ["name", "rate", "amount"],
        "properties": {
          "name": {
            "title": "Name of Tax",
            "description": "GST/PST etc",
            "type": "string"
          },
          "rate": {
            "title": "Tax Rate",
            "description": "Tax rate as a percentage",
            "type": "number"
          },
          "amount": {
            "title": "Tax Amount",
            "description": "Total amount of tax charged",
            "type": "number"
          }
        }
      }
    },
    "quantity": {
      "title": "Quantity",
      "description": "Number of units",
      "type": "integer"
    }
  }
}
```

このJSONスキーマは、デジタルレシート内の各項目（商品やサービス）の詳細情報を定義するためのものです。
以下に、スキーマの各部分の説明を示します。

- **type**
    - オブジェクトのタイプを指定します。
- **id**
    - スキーマの識別子です。

### 必須プロパティ
- **id**
    - 商品やサービスのユニークな識別子です。
- **title**
    - 商品やサービスのタイトル（名前）です。
- **date**
    - 商品やサービスが提供された日付です。
- **amount**
    - 1つの商品やサービスの単価（税を除く）です。
- **tax**
    - 商品やサービスに課金される税金の詳細情報を含む配列です。
- **quantity**
    - 商品やサービスの数量（単位数）です。

### その他のプロパティ
- **description**
    - 商品やサービスの説明です。
- **link**
    - 商品やサービスに関連するウェブページへのURLリンクです。
- **contract**
    - 商品やサービスに関連する外部契約のURLリンクまたはハッシュです。
- **serial_number**
    - 商品のシリアル番号です。

### 商品やサービスに関連する税金の詳細情報を定義するためのプロパティ
- **name**
    - 税の名前（例：GST/PSTなど）です。
- **rate**
    - 税率（パーセンテージ）です。
- **amount**
    - 課金される税金の総額です。

このJSONスキーマによって、デジタルレシート内の各商品やサービスに関する情報が構造化され、それぞれの情報項目に適切な形式と制約が設定されています。
これによって、トランザクションの詳細情報が正確かつ効率的に管理される仕組みが提供されます。

# 補足
この導入されたスキーマは、**ERC721**のメタデータ拡張に準拠しており、これによって以前から存在しているNFTの表示ツールが、新たに提供されたレシートを表示することができます。
新しいプロパティ「`receipt`」には、新しく提供されたレシートの構造が含まれており、また「`signature`」プロパティはベンダーがレシート構造にデジタル署名を行う際のオプションを提供します。

# 後方互換性
この標準は**ERC721**の拡張です。
**ERC721**で言及されているメタデータと**Enumerable**の2つのオプション拡張と互換性があります。

# セキュリティ考慮事項
デジタルレシートに格納されるデータには、ベンダーの名前、連絡先情報、購入したアイテムなどの個人を特定できる情報が含まれています。
個人を特定したり、位置を特定したり、連絡を取ったりするために使用される個人情報（PII）は、敏感な情報です。
顧客のプライバシーを保護することは非常に重要であり、無許可のPIIへのアクセスは、身元盗用、詐欺、その他の悪意のある活動につながる可能性があります。

顧客のプライバシーを保護するために、デジタルレシート内のPIIを暗号化することは非常に重要です。
PIIを暗号化することで、適切な復号化キーを持つ許可された関係者のみが、デジタルレシートに格納された情報にアクセスして読み取ることができます。
これによって、顧客のプライバシーが保持され、データが悪用されるリスクから保護されます。

PIIを暗号化することは重要ですが、特定の暗号化基準を定義することはこのERCの範囲外であることに注意することも大切です。

# 引用
Sean Darcy (@darcys22), "ERC-5570: Digital Receipt Non-Fungible Tokens," Ethereum Improvement Proposals, no. 5570, September 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5570.

# 考察
レシートをブロックチェーンに刻むのは面白い取り組みだなと思いました。
確かに後々確認するときに改ざんの心配がないので信頼できますね。
それに加えて、個人情報は暗号化しつつ、取引を行った証明を行うことができる点も良いですね。
問題点としては、レシートを登録するたびにガス代がかかることです。
いくらガス代が安くても、わざわざガス代をかけてレシートを登録する人がどれだけいるのかは疑問です。
その解決策としては、ガス代が安いチェーンやガス代が実質無料のチェーンなどですかね🤔
NFTマーケットプレイスで、NFTを購入したときに裏側で自動発行されるなどできると便利ですね。
マーケットプレイスのオフチェーンDB内でもその情報は管理していると思いますが、ブロックチェーン上でも管理することで信頼性が上がります。
あまり使われる場面を想像できないですが、これから何かで役立っていく可能性はありそうですね。

# 最後に

今回は「商品を購入したレシートをNFTのメタデータに書きこんで、ブロックチェーン上に書き込むことができる**ERC5570**」についてまとめてきました！
いかがだったでしょうか？

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

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

# 採用強化中！

CryptoGamesでは一緒に働く仲間を大募集中です。

https://www.wantedly.com/companies/cryptogames

この記事で書いた自分の経験からもわかるように、裁量権を持って働くことができて一気に成長できる環境です。
「**ブロックチェーンやWeb3、NFTに興味がある**」、「**スマートコントラクトの開発に携わりたい**」など、少しでも興味を持っている方はまずはお話ししましょう！