Used to check for browser translation.
用于检测浏览器翻译。
ブラウザの翻訳を検出する
Core Blockchain Concepts

Non-Fungible Tokens (NFTs)


Non-Fungible Tokens (NFTs) on the ArcBlock chain represent unique digital assets with distinct identifiers and metadata. They are a core component of the ArcBlock ecosystem, enabling the tokenization of various real-world and digital items.

For a broader understanding of fundamental blockchain concepts, refer to Core Blockchain Concepts. Specifically, NFTs often utilize Decentralized Identifiers (DIDs) for their unique identification.

What is an NFT?#

NFTs, or Non-Fungible Tokens, are cryptographic assets on a blockchain that possess unique identifiers and metadata, making each one distinct from another. Unlike fungible tokens (such as cryptocurrencies), NFTs cannot be exchanged on a one-to-one basis because each one has a unique value and properties.

On the ArcBlock chain, an NFT fundamentally represents data – any data that holds actual value and needs to be immutably recorded on the blockchain. Each NFT is identified by a Universal Unique Identifier (DID).

NFTs can represent:

  • Real-world tangible assets like artwork, real estate, or collectibles. Tokenizing these assets streamlines buying, selling, and trading processes while significantly reducing the risk of fraud.
  • Intangible digital assets, including individuals' identities, property rights, passports, event tickets, and digital certificates.

NFT Use Cases#

The application scenarios for NFTs are vast. Whenever you need to record unique, verifiable data on the blockchain, NFTs provide a robust solution. Common use cases include, but are not limited to:

  • Event Ticketing: Alice can create unique ticket NFTs for her event, allowing participants to purchase and hold verifiable proof of entry on the blockchain.
  • Certificates: An online learning platform can issue course completion certificates as NFTs. These digital certificates can then be used by students to prove qualifications for subsequent courses or professional recognition.
  • Membership Proof: Paid subscription platforms can issue membership certificates as NFTs, granting holders access to exclusive content or services. This provides a secure and verifiable way to manage access.

NFT Structure#

A typical NFT stored on the ArcBlock chain has a well-defined structure to ensure consistency and functionality. Below are the key fields that compose an NFT. The underlying type definition for an asset state can be found in TAssetState from @ocap/state.

Field

Type

Required

Default

Memo

Updatable

address

string

Yes

-

NFT identifier

No

owner

string

Yes

-

NFT owner identifier

Yes

issuer

string

Yes

-

NFT issuer identifier

No

parent

string

Yes

-

NFT Factory identifier

No

moniker

string

Yes

-

Human-readable name

No

readonly

boolean

Yes

false

Is the NFT immutable

No

transferrable

boolean

Yes

false

Can NFT be transferred after creation

No

consumedTime

Date

No

-

The consume date for the NFT

Yes

data

Any

Yes

false

The data that makes the NFT unique

Yes

display

object

No

null

The NFT display

No

endpoint

object

No

null

The NFT endpoint

No

tags

string[]

No

[]

List of tags for later filtering

No

NFT Extendability#

NFTs on the ArcBlock chain are designed for flexibility, allowing them to be either mutable or immutable based on specific application requirements. To further enhance their utility in real-world scenarios, ArcBlock introduces two customizable layers: NFT Display and NFT Endpoint.

NFT

NFT Display

NFT Endpoint

Visual Representation (SVG, Image URL)

Dynamic Attributes

Interactive Actions

DID Wallet Display


This diagram illustrates how NFT Display and NFT Endpoint extend the core NFT functionality to provide dynamic visual and interactive elements, often rendered in a DID Wallet.

NFT Display#

The NFT Display defines the visual representation of an NFT. An NFT can have:

  • An immutable display, typically for NFTs from sources like the Blocklet Store.
  • A mutable display, for instance, NFTs generated by the Blocklet Launcher.
  • No display at all.

The structure for NFT Display is defined as follows:

type NFTDisplay = {
// Can be svg|url|uri
type: string;

// Varies according to the type
// For svg type, content should be the svg itself
// For url type, content should be the url to fetch the display content, this URL will be requested with the NFT or the NFT address for the display
// For uri type, content should be the uri to resolve the display content, such as base64 encoded image
content: string;
};

Developers can define the NFT Display in two primary ways:

  • By setting the display field within the CreateAssetTx transaction.
  • By defining the output.display field when creating an NFT Factory using CreateFactoryTx.

NFT Endpoint#

The NFT Endpoint allows developers to extend NFT capabilities beyond static on-chain data, enabling dynamic attributes and actions off-chain. This is crucial for NFTs whose status or available actions change over time.

The structure for NFT Endpoint is defined as follows:

type NFTEndpoint = {
// the url that serve the endpoint, the url is requested with assetId and locale when displaying the NFT
id: string;

// can be public|private, private endpoints are requested with DID Connect
scope: string;
};

NFT Endpoints can be used to:

  • Display an NFT's status that may change dynamically.
  • Present actions associated with the NFT that might evolve over its lifecycle.

For example, a Blocklet Server Ownership NFT from Blocklet Launcher uses an NFT Endpoint to display its current status and provide interactive options to the owner.

NFT Factory#

An NFT Factory acts as a vending machine on the blockchain, allowing developers to create standardized NFTs efficiently. This is particularly useful for NFTs with common formats, such as event tickets or digital collectibles. Users can interact with an NFT Factory by sending transactions to pay for and acquire the NFTs it defines.

The following diagram illustrates the operational flow of an NFT Factory:

AcquireAssetV3Tx

Consumes Inputs

Sends NFT

Executes Hooks (Optional)

User

NFT Factory

Generates NFT

Custom Logic (e.g., Revenue Split)


This diagram shows how a user interacts with an NFT Factory, which consumes predefined inputs to produce and distribute new NFTs, optionally executing custom logic via hooks.

NFT Factory Transactions#

Several key transactions are involved in managing and interacting with an NFT Factory:

  • CreateFactoryTx: Used by developers to establish and configure a new NFT Factory.
  • AcquireAssetV3Tx: Used by users to purchase or obtain an NFT from a factory, typically involving payment or consumption of other assets.
  • MintAssetTx: Used by the factory owner to issue NFTs without requiring payment from the recipient, often for promotional or administrative purposes.

NFT Factory Inputs#

Factory inputs define the cost or requirements for acquiring a new NFT from the factory. These inputs can fall into three categories:

  • Tokens: Cryptocurrencies required as payment. A factory can specify up to 8 different tokens, each with its required address and value.
  • Assets: Existing NFTs that must be consumed to acquire a new one. These can be specific NFT addresses or even other Factory addresses. All specified assets are marked as consumed upon successful acquisition.
  • Variables: Extra information required from the user, typically collected via a form before the acquisition process.

Here's an example of a factory input structure from Blocklet Launcher:

{
"tokens": [
{
"address": "z35nNRvYxBoHitx9yZ5ATS88psfShzPPBLxYD",
"value": "299000000000000000000"
}
],
"assets": [],
"variables": [
{
"name": "plan",
"value": "",
"description": "",
"required": true
},
{
"name": "tag",
"value": "",
"description": "",
"required": true
}
]
}

NFT Factory Output#

The NFT Factory's output defines the predefined format for all NFTs it produces. Developers specify this format as a Mustache template, which generates a CreateAssetTx structure upon rendering (acquiring).

Here's an example of a factory output from Blocklet Launcher:

{
"moniker": "BlockletServerOwnershipNFT",
"data": {
"type": "json",
"value": {
"purchased": {
"plan": "{{input.plan}}",
"sku": {
"name": "{{data.name}}",
"type": "{{data.type}}",
"period": "{{data.period}}"
}
}
}
},
"readonly": false,
"transferrable": true,
"ttl": 0,
"parent": "{{ctx.factory}}",
"address": "",
"issuer": "{{ctx.issuer.id}}",
"endpoint": {
"id": "http://1322c65c-znkqyck3vfnye4cyk3yrwfnydgvvkshr9cur.did.abtnet.io/api/nft/status",
"scope": "public"
},
"display": {
"type": "url",
"content": "http://1322c65c-znkqyck3vfnye4cyk3yrwfnydgvvkshr9cur.did.abtnet.io/api/nft/display"
},
"tags": ["BlockletServerOwnershipNFT", "{{input.tag}}"]
}

The data consumable within an NFT factory output template includes:

  • input.*: Variables provided as input during the acquiring/minting transaction.
  • data.*: Immutable data object associated with the factory since its creation.
  • ctx.*: Contextual information at the time of acquiring/minting, such as:
    • ctx.factory: The address of the NFT factory.
    • ctx.id: The current mint sequence number (factory.numMinted + 1).
    • ctx.issuer.id: The address of the NFT issuer.
    • ctx.issuer.pk: The public key of the NFT issuer.
    • ctx.issuer.name: The moniker of the NFT issuer's account.
    • ctx.owner: The address of the NFT owner.

NFT Factory Hooks#

Developers can integrate custom logic into the NFT acquisition process using factory hooks. These hooks execute specific actions when a new NFT is successfully acquired from a factory.

For example:

  • The Blocklet Store utilizes factory hooks to automatically split revenue between the Blocklet developer and the store when a user purchases a paid Blocklet.
  • NFT minting tools can use hooks to distribute revenue between the developer and the NFT provider.

Factory hooks are configured and become immutable when the CreateFactoryTx is sent. Here's an example of a mint hook from the Blocklet Store:

[
{
"name": "mint",
"type": "contract",
"hook": "transferToken('z35nNRvYxBoHitx9yZ5ATS88psfShzPPBLxYD','z1gShFYDsiMfGtaerBTh2ydu75768xMYPQU','4662000000000000000');\ntransferToken('z35nNRvYxBoHitx9yZ5ATS88psfShzPPBLxYD','zNKXtdqz6Jbw5mKpojK2nP5gRNiEGJY3mNFF','1998000000000000000')"
}
]

This mint hook uses the chain's experimental contract feature, specifically the transferToken function:

transferToken(
"z35nNRvYxBoHitx9yZ5ATS88psfShzPPBLxYD", // token address
"z1gShFYDsiMfGtaerBTh2ydu75768xMYPQU", // receiver address
"4662000000000000000" // token amount in big number
);

Token transfers within factory hooks are subject to the following restrictions:

  • The total revenue split must not exceed the initial factory input token amount.
  • All specified token receiver addresses must exist in the ledger.
  • All specified token addresses must exist in the ledger.

NFT Factory Data#

NFT factories can have custom data attached to them during creation. This data can then be referenced and utilized within the NFT output templates during the acquiring or minting process.

  • NFT factory data is copied directly from the CreateFactoryTx.
  • This data supports the Any Type, allowing for flexible data structures.

NFT Security#

Security is paramount for digital assets like NFTs. ArcBlock's design incorporates several considerations to ensure the integrity and privacy of NFTs.

Privacy Considerations#

Once an NFT is stored on the blockchain, its on-chain information is publicly viewable by anyone with the NFT's address. While any data can theoretically be stored within an NFT, developers should choose the storage method based on privacy requirements:

  • Weakly Typed Data (Publicly Verifiable): For non-sensitive data, such as a certificate's core details, storing it in plain JSON allows for full public verifiability.
  • Strongly Typed Data (Partial Privacy): NFT data can be saved in a serialized Any Type format. While this prevents direct decoding without the NFT data proto-buffer, some fields might still be technically viewable.
  • Sensitive Data (Off-Chain Storage): For highly sensitive information like contracts or pay slips, the NFT should only store a hash of the original data. The actual sensitive data should be stored securely in an off-chain database, and access to it should be controlled.

Prevent Counterfeiting#

The ArcBlock chain includes built-in logic to prevent the creation of identical NFTs, ensuring that each NFT is truly unique. However, developers must implement strict verification logic in their applications to prevent mistakenly treating a fake NFT as genuine. One effective solution is to attach the issuer's signature during NFT creation, which allows for easy and reliable verification of authenticity.


This section provided a detailed overview of Non-Fungible Tokens (NFTs) on the ArcBlock chain, covering their definition, structure, use cases, and the powerful concept of NFT Factories. You now have a solid understanding of how NFTs are designed and managed in the ArcBlock ecosystem.

To learn how to interact with NFTs on the blockchain, proceed to the NFT Transactions section.