Alert Source Discuss
Standards Track: ERC

ERC-5570: Digital Receipt Non-Fungible Tokens

Non-Fungible Tokens as digital receipts for physical purchases, where the metadata represents a JSON receipt

Authors Sean Darcy (@darcys22)
Created 2022-09-01
Requires EIP-721

Abstract

This ERC proposes a standard schema for digital receipts of transactions. Digital Receipt Non-Fungible Tokens are issued by a vendor when a customer makes a purchase from their store and contains transaction details necessary for record keeping. Digital Receipt Non-Fungible Tokens extend ERC-721 which allows for the management and ownership of unique tokens.

Motivation

Purchases from online retailers include a receipt that is emailed and/or physically provided to the customer. These receipts are critical for many reasons but are provided in an analogue form which is difficult to parse by financial systems. Digital receipts have never gained traction dispite the fact that point of sales systems are already digital and the customers often want this information in their own digital systems. So we are left with a redundant Digital -> Analogue -> Digital process which requires unnecessary data entry or the use of clunky receipt-scanning applications.

Digital receipts are relatively simple and can be specified with a schema that can be parsed into JSON or other structured formats. In addition we can prove the receipts validity by digitally signing the receipt using the vendors private keys.

As Ethereum scales tooling will need to be developed to provide end users with features (such as receipts) already available to fiat transactions. NFTs provide a unique opportunity to link an on chain purchase with its transaction details directly through the transaction state update. If we conceptually think of a transaction as funds provided to one participant and goods provided to another, then our real life state includes two sides of a transaction, 1) Funds changing ownership and 2) goods changing ownership. NFT receipts are first class citizens of a transaction reflecting the goods changing ownership as part of the transaction state. They will bring our on chain transaction state in line with the changes happening in the real world.

The convenience of a direct link to the transaction receipt via the transaction state is significant, other methods of distributing receipts either off chain or through smart contracts separate to the initial transaction lose this link and force the end user to manually locate the transaction details when needed. The benefit can be demonstrated by comparing a wallet that allows a user to click through a transaction to its receipt (available immediately after purchase without any further action) verses a user needing to search through a datastore to locate a receipt for a transaction that they can see in their wallet history.

Digital receipt as NFTs can also conceptually include other important information such as item serial numbers and delivery tracking etc.

One of the major roadblocks to fully automating our finance world has been the difficulty in tracking transaction details. Human beings physically tracking paper receipts is archaic and NFTs on the blockchain provide a pathway for these systems to be significantly improved.

Specification

Transaction Flow:

  • A customer purchases an item from an online retailer, checking out leads the customer to an option to mint a NFT.
  • The smart contract provides the user with a Digital Receipt Non-Fungible Token.
  • When fulfilling the order, the retailer will upload the digital receipt specified in in the JSON schema below as the metadata to the previously minted NFT.

Digital Receipt JSON Schema

The JSON schema is composed of 2 parts. The root schema contains high level details of the receipt (for example Date and Vendor) and another schema for the optionally recurring line items contained in the receipt.

Root Schema

{
  "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"
    }
  }
}

Line Items Schema

{
  "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"
    }
  }
}

Rationale

The schema introduced complies with ERC-721’s metadata extension, conveniently allowing previous tools for viewing NFTs to show our receipts. The new property “receipt” contains our newly provided receipt structure and the signature property optionally allows the vendor to digitally sign the receipt structure.

Backwards Compatibility

This standard is an extension of ERC-721. It is compatible with both optional extensions, Metadata and Enumerable, mentioned in ERC-721.

Security Considerations

The data stored in the digital receipt includes various types of personally identifying information (PII), such as the vendor’s name, contact details, and the items purchased. PII is sensitive information that can be used to identify, locate, or contact an individual. Protecting the privacy of the customer is of utmost importance, as unauthorized access to PII can lead to identity theft, fraud, or other malicious activities.

To ensure the privacy of the customer, it is crucial to encrypt the PII contained within the digital receipt. By encrypting the PII, only authorized parties with the appropriate decryption keys can access and read the information stored in the digital receipt. This ensures that the customer’s privacy is maintained, and their data is protected from potential misuse.

While encrypting PII is essential, it is important to note that defining a specific encryption standard is beyond the scope of this ERC.

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

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.