Business Model Innovation Through Fractional NFT
Earlier this year we released ERC-1155 compliant fungible and non-fungible token support using Blockchain App Builder - a low-code development toolset for Oracle Blockchain Platform (OBP). With the ERC-1155 standard, application developers can create fungible and non-fungible tokens using a single chaincode. We always believe in simplicity, and ERC-1155 makes chaincode development and maintenance even simpler and easier. We extended ERC-1155 support with 40+ REST APIs to create the complete token life cycle and expedite the launch of any token application in the market. In September, we released fractional non-fungible token (fractional NFT) support based on ERC-1155 to automatically generate the complete life cycle of fractional non-fungible tokens.
The fractionalisation of an asset is an important concept in asset tokenisation. When an asset value increases, the propensity to purchase the asset diminishes. It makes the asset illiquid. The fractionalisation of an asset creates a business model innovation where a buyer can purchase a fraction of a high-value asset. The purchase of a fraction of a high-value asset increases the propensity to purchase and sell assets in a marketplace and increases the liquidity of the asset. The fractional NFT fosters shared ownership of high-value assets and promotes inclusivity to create a more democratic NFT marketplace.
Fractional NFT brings innovation into real-world businesses. For example, a real estate property or a fine art piece can be owned by multiple owners, an intellectual property can be tracked easily to share it across multiple organisations or the musicians, publishers, and sports leagues can better fund their new work and strengthen the ties with the fans through crowd-sourcing. Creative community can license their works to multiple organizations based on regional scope or other factors as fractions of the original NFT representing the license. Grant award letters represented as NFTs can be traced not only to the immediate grant recipients, but also to sub-grantees, which is often the case with government grants that are further subdivided by initial recipients into sub-grants.
Blockchain App Builder empowers the application developers to automatically generate fungible and non-fungible token chaincodes, deploy, test, and debug the chaincodes on local Hyperledger Fabric or Oracle Blockchain Platform Cloud Services. Blockchain App Builder now also bolsters business model innovation through fractional NFT. We strongly believe that the tokenization in blockchain is not only about cost optimisation but also about increasing revenue. A revenue increase is possible when more people participate in a marketplace, and fractional NFT helps the business increase participation.
In this post, we illustrate how to use the fractional NFT capabilities by implementing a fractional non-fungible token use case for NFT real estate property marketplace.
The implementation of NFT can be done in 4 easy steps:
- Asset declaration in the specification template
- Auto-generation of the fractional NFT chaincode with all the core lifecycle methods (create, transfer, etc.)
- Addition of custom logic for the chaincode methods to handle additional marketplace functionality
- Testing of fractional NFT chaincode with REST APIs
Example of Fractional NFT Use Case
To illustrate the fractional NFT implementation using Blockchain App Builder, we have selected a use case of a real estate property marketplace to simulate the partial ownership of real estate properties. The NFT platform provider onboards real estate developers in the platform. The developers (builders) create a fractional NFT for a property and create the total token share quantity for that property NFT. For example, a real estate builder can create a 10 token share quantity for the NFT representing a 2000 square feet property worth $500,000. It suggests that one token share represents 200 square feet of the property, and the buyer can purchase the rights to one token share representing 10% for $50,000.
If two property buyers purchase 2 token shares and 3 token shares from the real estate builder respectively, then the buyer-1 has to pay $100,000 for 2 token shares (i.e. 400 square feet of the property) and the buyer-2 has to pay $150,000 for 3 token shares (i.e. 600 square feet of the property). The real estate builder can periodically set the selling price of the property based on the market value. If the selling price for the entire property reaches $600,000 based on the market value, then buyer-1 can sell the 2 token shares at $120,000 with a profit of $20,000.
The real estate builder can also rent out the property. The buyers who own the percentage token share in the property can also get the equivalent percentage share from the renting amount.
Figure 1. Fractional NFT in Real Estate Property Marketplace: Seller creates the fractional NFT for the property and creates total token shares
Figure 2. Fractional NFT in Real Estate Property Marketplace: Buyer purchases fractional ownership by paying an equivalent amount of the selling price through a payment gateway
Specification Template
A sample template is included in the Blockchain App Builder’s Visual Studio Code (VSC) extension under Specifications, or you can download it from the OBP Console > Developer Tools in the Blockchain App Builder page. The specification template can be created in yaml or json. The template for NFT chaincode auto-generation consists of the following sections.
- Token model
assets:
- name: RealEstateProperty #Asset name
type: token # Asset type
standard: erc1155+ # Token standard (extended version of ERC-1155 spec)
anatomy:
type: nonfungible # Token type
unit: fractional # Token unit
Based on the ERC-1155 standard support for fractional NFT users can specify the token standard as erc1155+. The “+” symbol in token standard signifies that we support additional capabilities and methods beyond the ERC-1155 standard to make NFTs more dynamic and NFT applications more flexible. Then in token anatomy section specify type as nonfungible and unit as fractional.
- Token behaviours
behavior:
- divisible
- mintable:
- transferable
- roles:
minter_role_name: minter
Based on the selection of the token behaviors, the NFT life-cycle methods are auto-generated. In roles behaviour, you can specify roles to be supported for minting and/or burning operations – in the example below, we specify a “minter” role. When the minter role is specified in the specification file, you need to assign the user who can create / mint the fractional NFT using generated API. In addition to the token data asset, we also generate and maintain Custodial Wallets on chain. These are identified by user’s OrgID (instance owner’s MSPId or custom enrollment ID for a client organization) and UserID, and can be managed by the generated methods and APIs.
- Custom attributes
properties: # Custom asset attributes for non-fungible token
- name: propertySellingPrice # Custom asset attribute to set the real estate property price
type: number
- name: propertyRentingPrice # Custom asset attribute maintains the renting amount for the real estate property
type: number
We extend the fractional NFT for our use case with two custom attributes: property selling price, to specify the selling price of the real estate property NFT and property renting price, to specify the renting amount of the real estate property NFT. Custom attributes are can be dynamically updated by the NFT owner.
- Metadata attributes
metadata: # To maintain the metadata on-chain, this tag will be used. Once token has been created, users won't be able to update the metadata attribute values.
- name: propertyType
type: string
- name: propertyName
type: string
- name: propertyAddress
type: string
- name: propertyImage
type: string
You have the option to maintain a copy of the metadata attributes on-chain to describe the NFT. In this example we define attributes like property type, property name, property address, and property image. Unlike custom attributes, which current owners can update as needed, metadata attributes are provided when the NFT is being created and can’t be modified afterwards.
- Custom methods
customMethods:
- executeQuery
- "setPropertySellingPrice(tokenId: string, propertySellingPrice: number)" # Set the property selling price
- "setPropertyRentingPrice(tokenId: string, propertyRentingPrice: number)" # Set the property renting price
- "buyProperty(fromOrgId: string, fromUserId: string, toOrgId: string, toUserId: string, tokenId: string[], tokenShare: number[], sellingAmountPaid: number)" # Buy the real estate property non-fungible token share after paying the amount using any payment gateway
These methods are specified here so developers can add specific business functionalities through the custom methods. All of the other methods and APIs required to manage the NFT lifecycle from initialization to creation and transfer along with account create and roles management and various queries, are generated automatically when you create the chaincode using this template. Note that executeQuery is a method that is also pre-generated and exposed as an API for generic queries on the state database.
The setPropertySellingPrice, setPropertyRentingPrice and buyProperty methods are generated as function signatures where users can add custom business logic leveraging the underlying token SDK methods generated by the App Builder. With ERC1155+ token standard type, you can also include fungible token, non-fungible token and non-token assets in the same single specification file and all the relevant methods for these assets will be generated as well.
Generating Fractional NFT Chaincode
Once the template has been tailored, you can generate the chaincodes in the App Builder. In the Visual Studio Code extension GUI click the “+” icon to the right of the Chaincodes section, which will bring up the pop up on the right where you can create the chaincode.
Figure 3. Blockchain App Builder - Auto-generating Chaincode
Simply fill in the chaincode name, select TypeScript in the language dropdown, pick your template from the dropdown list, fill in Location for scaffolding the project (only if generating TypeScript), select “Enable MVCC optimization” checkbox, and click “Create” button to scaffold the project and generate the chaincode. The specification file is specific to TypeScript since three custom method signatures are specified where parameter types are language specific. If you want to generate the chaincode in Go, then change the parameter specification and data type in the custom method signature to be compatible with Go (e.g., number type changes to int.)
Custom Methods
After scaffolding the project in TypeScript, the custom methods’ (i.e., setPropertySellingPrice, setPropertyRentingPrice and buyProperty) logic needs to be updated in controller.ts file under src directory.
The custom method “setPropertySellingPrice” will set the property NFT selling price using the sample code below.
@Validator(yup.string(), yup.number())
public async setPropertySellingPrice(tokenId: string, propertySellingPrice: number) {
try {
const token = await this.Ctx.ERC1155Token.get(tokenId);
const t = new RealEstateProperty(token);
t.propertySellingPrice = propertySellingPrice;
await this.Ctx.ERC1155Token.update(t);
let msg = `Token ID : '${tokenId}' has been updated with latest property selling price'`;
return {msg}
} catch(error) {
throw new Error(error.message);
}
}
The custom method “setPropertyRentingPrice” will set the property NFT renting price using the sample code below.
@Validator(yup.string(), yup.number())
public async setPropertyRentingPrice(tokenId: string, propertyRentingPrice: number) {
try {
const token = await this.Ctx.ERC1155Token.get(tokenId);
const t = new RealEstateProperty(token)
t.propertyRentingPrice = propertyRentingPrice;
await this.Ctx.ERC1155Token.update(t);
let msg = `Token ID : '${tokenId}' has been updated with latest property renting price'`;
return {msg}
} catch(error) {
throw new Error(error.message);
}
}
The “buyProperty” custom method is called by the buyer to purchase a fraction of the property NFT from the real estate builder.
@Validator(yup.string(), yup.string(), yup.string(), yup.string(), yup.array().of(yup.string()), yup.array().of(yup.number()), yup.number())
public async buyProperty(fromOrgId: string, fromUserId: string, toOrgId: string, toUserId: string, tokenId: string[], tokenShare: number[], amountPaid: number) {
try {
const token = await this.Ctx.ERC1155Token.get(tokenId[0]);
const t = new RealEstateProperty(token);
const sellingAmountShare = (t.propertySellingPrice/t.quantity)*tokenShare[0]
let msg = `'${tokenShare[0]}' token shares of Token ID : '${tokenId}' has not been transferred'`;
if (sellingAmountShare === amountPaid) {
const from_account_id = await this.Ctx.ERC1155Account.generateAccountId(fromOrgId, fromUserId, ACCOUNT_TYPE.USER_ACCOUNT);
const to_account_id = await this.Ctx.ERC1155Account.generateAccountId(toOrgId, toUserId, ACCOUNT_TYPE.USER_ACCOUNT);
await this.Ctx.ERC1155Token.batchTransferFrom(from_account_id, to_account_id, tokenId, tokenShare);
await this.Ctx.Model.update(t);
msg = `'${tokenShare[0]}' token shares of Token ID : '${tokenId}' has been successfully transferred to UserID : '${toUserId}'`;
}
else {
throw new Error(`'${tokenShare[0]}' token shares of Token ID : '${tokenId}' has not been transferred to UserID : '${fromUserId}' as the amount paid : '${amountPaid}' is not equal to the selling amount share : '${sellingAmountShare}'.'`);
}
return {msg};
} catch(error) {
throw new Error(error.message);
}
}
Once you’ve copied these methods into the controller.ts and saved the chaincode, you can deploy it to your Oracle Blockchain Platform instances using the Deploy tab. While deploying the NFT chaincode using Blockchain App Builder Visual Studio Code extension, you need to pass Org ID and User ID of the token admin to initialize the NFT chaincode. Once chaincode has been deployed, the token admin will be able to create the NFT accounts, assign NFT minter role to the users and will be able to add other admin users.
Testing of Fractional NFT Chaincode with REST APIs
For testing of Fractional NFT chaincode, we can invoke the chaincode methods using REST APIs. REST APIs can be tested easily using Postman, a popular test tool for REST APIs. These APIs can be easily integrated into other systems or custom front-ends, such as a Web or Mobile application. The sample Postman collection file can be downloaded from OBP console > Developer Tools using the link “Download Specification Samples and Related Code” under "Specification Samples". Unzip the downloaded "obp-app-builder-samples" file and go to “FractionalNFTinRealEstate” folder. Import the “Fractional NFT in Real Estate - TypeScript.postman_collection.json” postman collection into Postman.
The fractional NFT chaincode testing can be done in 7 easy steps, as shown in the diagram below.
1. Create user account and an NFT account
2. Add a minter role to the user account for the NFT asset
3. Create real estate property NFT
4. Set real estate property selling price
5. Buy a fraction of the real estate property NFT in the marketplace
6. Track the complete history of the property NFT
7. Get the account details by user
Figure 4. Real Estate Property Marketplace
From “How to Setup and Transact NFTs on Oracle Blockchain” blogpost on ERC-721 compliant NFTs, you can refer “Create NFT accounts” on how to create the Identity Cloud Service (IDCS) users and how to create the user identities on Hyperledger Fabric.
Note that you must open the Postman collection variables tab to set the variable values. These values will be re-used in all the API calls.
Figure 5. Postman collection with the updated variable values
1. Create User Account and NFT Account
Once the user identities and custom enrollments have been set up, the NFT admin can create NFT accounts on-chain by invoking the auto-generated method “createAccount”. The “createAccount” method can create a user account and, under that user account, create a fungible token account and an NFT account within a single transaction. One user account can hold multiple fungible token accounts and only one NFT account. Each userId within an orgId will have only one user account.
Figure 6. Postman request/response for createAccount API
The custodial wallet user account along with the NFT token account has now been created; note that in the response body, the result includes the blockchain transaction id as well as a payload indicating asset type “ouaccount” and its properties – accountID, userID and orgID associated with the account, the associated NFT account id and current number of NFTs in the account.
Additional accounts for other real estate builders and marketplace users can be created using the same API with changing values of orgID and userID in the request body.
2. Add Minter Role to the User Account for the NFT Asset
The NFT admin can specify which user will be able to mint an NFT by assigning the minter role to the NFT account. NFT admin will invoke the auto-generated method “addRole” to assign minter role to an existing NFT account for a specific NFT asset.
The account specified can now mint or create NFTs, and the transaction ID associated with this on-chain is returned in the response result along with the Success message. You can add this role for any other accounts of real estate builders.
Figure 7. addRole API
3. Create Real Estate Property NFT
The user with the minter role can create / mint NFT by invoking the auto-generated method “createRealEstatePropertyToken”. Note that the method includes the class name “RealEstateProperty” in its name since it was generated from the template for the RealEstateProperty NFT class. After minting the NFT, the token will be automatically owned by the user who minted the token and will be in their custodial wallet.
Figure 8. createRealEstatePropertyToken API
4. Set Real Estate Property Selling Price
Real estate builder can set the property selling price and can update it based on the market price.
Figure 9. setPropertySellingPrice API
5. Buy a Fraction of the Real Estate Property NFT in the Marketplace
Once the property NFT is minted and the selling price is set, any user, who is not the current NFT owner, can now buy a fraction of the property NFT. The payment integration is not shown in this example, but a marketplace app can integrate with a variety of payment gateways using published APIs to process fiat payments; for example using Oracle Integration Cloud PayPal adapter, Oracle Monetization Cloud, or more flexible Oracle CX Commerce payment options. Or you can use OBP Fungible Tokens, possibly funded by a fiat payment or exchange of crypto tokens from a public blockchain, and then handle NFT payments as a Fungible Token transfer from buyer’s to seller’s account.
Once a payment has been processed, the marketplace can invoke the custom method “buyProperty” to transfer a token share of the real estate property NFT from the real estate builder’s wallet (i.e. NFT minter’s account) to the new buyer’s account.
Figure 10. buyProperty API
6. Track the Complete History of the Property NFT
Any user can track the complete history of the property NFT by using REST APIs to invoke the auto-generated method “getTokenHistory” via the “chaincode-queries” URI instead of the “transaction” URI.
Figure 11. gertTokenHistory API
7. Get the Account Details by User
Any user can check his own user account details by invoking the auto-generated method “getAccountDetailsByUser” using the “chaincode-queries” instead of the “transaction” in the URI. The response will show the NFT ID and the associated token share owned by the user in his NFT account.