# Creating non-fungible tokens with ERTP

# Definition of fungible/non-fungible

Assets are fungible if each asset is just as valuable as other assets of the same kind. For instance, dollar bills are fungible because it doesn't matter which bill you use. Each dollar bill is interchangeable with any other. Paintings, on the other hand, are not fungible. Paintings have drastically different values depending on the content and painter. A deal involving a specific painting would not be satisfied by another painting.

# Creating a non-fungible asset with ERTP

# Modeling and creating the asset

In ERTP, digital assets are created by a mint. Having access to the mint gives you the power to create more digital assets of the same type at will.

Let's say we own an Opera and want to sell tickets to seats for ballet shows. Tickets are the non-fungible assets we want to represent. Tickets refer to a specific seat for a specific show at a specific time and date.

To do that, you would first install the ertp JavaScript package (npm install @agoric/ertp) and then:

import { makeMint } from '@agoric/ertp';

import harden from '@agoric/harden';

import { noCustomization } from '@agoric/ertp/core/config/noCustomization.js';
import { makeCoreMintKeeper } from '@agoric/ertp/core/config/coreMintKeeper';

import { insist } from '@agoric/insist';
import { mustBeComparable } from '@agoric/same-structure';

const insistOptDescription = optDescription => {
  insist(!!optDescription)`optDescription must be truthy ${optDescription}`;

function makeBalletTicketConfig() {
  return harden({
    makeMintKeeper: makeCoreMintKeeper,
    extentOpsName: 'uniExtentOps',
    extentOpsArgs: [insistOptDescription],

const balletTicketMint = makeMint('Agoric Ballet Opera tickets', makeBalletTicketConfig);

At this Opera, there are 1114 seats numbered 1 to 1114. Objects that represent valid tickets will have the following properties:

Let's create the tickets in ERTP! The first step is to create JavaScript objects, each representing a ticket. Then, only units can be minted, so let's create units from the JavaScript objects and then, let's mint the tickets!

const startDateString = (new Date(2019, 11, 9, 20, 30)).toISOString();

const ticketObjects = Array(1114).fill().map((_, i) => ({
  seat: i+1,
  show: 'The Sofa',
  start: startDateString,

const ticketUnits = ticketObjects.map(ticketExtent => balletTicketMint.getAssay().makeUnits(ticketExtent));

const balletTicketPurses = ticketUnits.map(ticketUnit => balletTicketMint.mint(ticketUnit))

For each ticket unit, we've created a purse which contains the corresponding unit. These purses can later be transformed into payments via a call to balletTicketPurse.withdrawAll(). This payment can then be bought and sold and used in smart contracts.