Including a code sample using the ERC721 standard.
"I've always been a sharing person." - Young Thug
In this article I’m going to implement a tokenization contract for digital assets that is both simple and effective. Please feel free to reuse the code if you find it useful.
The second purpose of this article is to show why some use cases for blockchain development are promising and others are more in doubt. Often the key is in whether decentralization is reasonable or not.
Blockchain allows us to build software that works in a different way from traditional solutions. With blockchain you can build decentralized applications that can be trusted to store data that hasn’t been tampered with. Decentralization is a necessary requirement, you could develop many different blockchain solutions but for any of them to reach a profitable scale you have to accept that you won’t control it. It’s a tricky one.
An example of a use case where decentralization works is Bitcoin. Its implementation as a trusted blockchain application enabled Bitcoin to grow organically without any centralized control or strategy. Bitcoin became some sort of currency or asset and made some people very wealthy as enough people decided it had value.
Now it is possible to build blockchain applications easily on top of platforms such as Ethereum or Hyperledger and the amount of ideas trying to exploit the blockchain opportunities has exploded.
A common pattern for blockchain applications is the implementation of some market. Many markets in the world are highly inefficient and market makers charge a large proportion of the proceedings. Blockchain by nature requires to remove intermediaries, returning the intermediation costs to the users.
With blockchain you can build decentralized applications that can be trusted to store data that hasn’t been tampered with.
Decentralizing a market is not always simple. In a previous article I gave an example of how real estate can be tokenized and real estate assets easily converted into blockchain-based REITs (Real Estate Investment Trusts). But even with a good implementation, decentralization is challenging in real estate markets due to trading with heavily regulated physical assets. This undermines the viability of the solution.
When discussing tokenization schemes I like to make a very clear distinction between physical and digital assets. When tokenizing physical assets there are complex relationships with the physical world. Questions like who physically holds the asset are important. Given that one of the main things that you can do with an asset is to transfer it you need to synchronize the token transfer with the asset transfer which is not an easy task.
Tokenizing digital assets is much simpler. You can use a token representation of your digital asset and integrate the token with the asset very easily. We can easily automate whole business processes. Let's see an example.
In our business case we are going to manage software licenses in a blockchain platform. These licenses are going to use a pay-per-use model. That’s it, easy.
Pay-per-use is a valid monetization process but it is quite cumbersome in managing the licenses. Offline licenses are often easy to crack and to have online licenses you need to maintain the servers. At the very least it will be a bit of a headache.
Using blockchain we can implement an efficient license system. Other features that we are going to include is a facility that collects payments to top up the licenses, and the opportunity for users to trade their licenses if they wish to do so. In addition to all this, maintaining the license system will be paid for by the users at a very low rate.
An ERC721 contract generates uniquely identifiable tokens which cannot be merged or broken down into fractions. These are very useful features for tokenizing assets and that often makes the ERC721 contract the ideal starting point for such schemes.
The best known example for an ERC721 token are cryptokitties. These are digital pets that are identical except for some aesthetic features coded in their identifier. You can easily see that any two cryptokitties are different, and you can’t divide or merge cryptokitties.
Cryptokitties are quite popular, but they are not the kind of example that sends business minds flying. I prefer to show an example that people can make money with.
Our license management contract is going to use the ERC721 standard. I suggest that you have a look at the code even if you are a business person. Even if you don't know how to code you should get an idea of what you can do by reading the method names and the comments.
An ERC721 contract generates uniquely identifiable tokens which cannot be merged or broken down into fractions.
In our contract each token generated represents one license to use the software. Whoever holds that token is licensed to run the software. If the token is transferred, so is the access to the software.
The licenses will expire after some time and they will have to be topped up to remain valid. For that we are going to create an additional mapping between licenses and expiration dates. We will have one method that accepts Ether and pushes the expiration date of the licenses into the future.
After that we only need one more method to check expiration dates which is very simple. The full contract is below:
pragma solidity ^0.5.0;
import "openzeppelin-solidity/contracts/token/ERC721/ERC721.sol";
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import "openzeppelin-solidity/contracts/math/Math.sol";
/**
* @title License Token
* @author Alberto Cuesta Canada
* @notice Implements an ERC721 license token with validity by top up.
*/
contract LicenseToken is ERC721, Ownable {
event TopUp(uint256 licenseId, uint256 expire);
/**
* @notice mapping from token id to expire date (in unix time)
*/
mapping(uint256 => uint256) internal expire;
/**
* @notice Delay the expiration of a license by a second per wei.
* @param _licenseId The license id.
*/
function topUp(uint256 _licenseId)
external
payable
{
uint256 timeToAdd = msg.value;
expire[_licenseId] =
Math.max(now, expire[_licenseId]) + timeToAdd;
emit TopUp(_licenseId, expire[_licenseId]);
}
/**
* @notice Mint new licenses, only owner.
* @param _to The address to receive the license.
* @param _licenseId The unique license id.
*/
function mint(address _to, uint256 _licenseId)
public
onlyOwner()
{
_mint(_to, _licenseId);
}
/**
* @notice Retrieve an expire date for a license
* @param _licenseId The license id.
*/
function getExpire(uint256 _licenseId)
public
view
returns(uint256)
{
return expire[_licenseId];
}
}
Tokenization of assets in a blockchain is a popular concept but not all use cases are equally suitable for it. Tokenization of digital assets is a perfect fit that allows to produce simple yet efficient implementations. Automation is frequently seen as one of the benefits of blockchain, but automation is only natural for digital assets.
The ERC721 contract gives us very useful functionality that can be used in a variety of schemes, always with the condition that the assets need to be truly unique, indivisible and susceptible to be traded.
The software license use case presented is a good fit for a tokenization with an ERC721 standard. Other use cases should be tokenized with an ERC20, a custom contract or not tokenized at all. Deep knowledge of the business environment and an open mind on how to monetize a decentralized solution are key.