I. Introduction and Inspiration
Currently, the ticketing industry is massive, and growing at a rapid rate. The global online ticketing market size is expected to reach 68 billion USD by 2025 [1] with a 4.8% CAGR, while the secondary ticket is expected to reach almost 10 billion USD by 2027 with a CAGR of 9.2% [2]. The smart ticketing industry is also expected to reach 16 billion USD by 2026, with a staggering CAGR of 14.5% [3]. Despite the seemingly dated origins of ticketing, it is clear that this industry still has a long way to grow.
A large part of the ticketing industry today still makes use of paper tickets, because they provide a simple, tangible and physical means of verification, and how they can be made more difficult to fake with custom prints and designs. Recently, many ticketing providers have switched to issuing electronic tickets instead, as they are less easily lost, simpler to deliver, and can be easily scanned upon entry.
However, most implementations of electronic tickets revolve around the use of a static code, which is then displayed or printed as a barcode or a QR code. The static nature of this code means that it can be easily duplicated and faked by resellers online, and often it is not easy to verify the authenticity of resold tickets, because ticketing providers do not expose public methods for validating these. Additionally, it is impossible to guarantee if a ticket has not been duplicated before.
Online ticket scalping is also a growing problem of late. In spite of efforts to prevent bot-puchases of e-tickets, traditional online ticketing providers are still not able to fully resolve this problem, leading to many real fans being unable acquire the tickets that they want, and having to pay higher prices to scalpers who are simply seeking to make a profit off of this.
NFTs and blockchain technology seems poised to tackle all of the issues with traditional e-tickets, with none of the drawbacks. However, most current NFT ticketing providers either do not have a publicly accessible or working product, or require contacting the project team to set up sales. This may seem unintuitive and rather intimidating, especially for smaller creators looking to launch their events using this technology. This is in contrast to popular ticketing platform Eventbrite, where anyone can sign up for an account to create events and tickets, albeit needing to purchase their higher ticketing packages for more complex events. Many ticketing providers are also not designed in a decentralised way, and merely use the blockchain to store hashes, while ticket metadata is still being stored centrally.
II. Our solution - TKETS
Most blockchains have an NFT minter and marketplace, but these are severely under-utilised as of today, with most projects revolving around collector's art pieces. We aim to bring more functionality and utility to NFTs than simply collecting and reselling, in a way that is user-friendly and accessible to most people. Therefore, we created TKETS, one of the first fully permissionless and decentralised NFT ticketing platforms on any blockchain. Fully permissionless, meaning that anyone who has a Metamask wallet can interact with our platform and create an event directly. There is no need to contact anyone for sales or a demo, or need for any sign-up or platform-dependent KYC.
We also designed our platform in a decentralised manner as far as possible. TKETS never holds centralised ownership of any NFTs, and NFT tickets are directly minted into the attendee wallet addresses. We also store ticket metadata, including the event name, ticket type, and NFT media, directly on IPFS. This information is also easily accessible on our platform, so anyone can pin the metadata for their own tickets to secure their availability for the future. Therefore, tickets sold will forever be owned by the ticket owners, and no central entity is able to fully remove or delete them. However, this brings some legal concerns regarding GDPR, which will be further discussed in Section III.
Next, our solution introduces a secure way for ticket scanning. Each ticket is able to generate a 1-minute QR code that contains information about what wallet address owns which ticket, which is then signed securely using that wallet address' private key. Our event factory smart contract contains a validateTicket function, which then can be used to validate this signature against the current information on the blockchain. More details about this is described in Section III. Since all ticket ownership information is held on the blockchain, this allows anyone to verify ticket ownership information, and guarantee the authenticity of a ticket. As each QR code is dynamic, tickets are then impossible to fake or duplicate, which virtually eliminates ticket fraud.
Also, our platform allows for direct payments. For event organisers, each ticket is minted as a separate smart contract that only they own, and every ticket purchase locks the funds directly into the contract. This means that after the event ends, event organisers can withdraw their funds immediately and directly, no need for any other approval.
Finally, we have also built an openly accessible Graph node API, which allows for 3rd party developers to easily query and develop their own applications on top of TKETS. This then opens our NFT tickets to even more possibilities. For example, websites and streams can query the API and allow for custom gated-entry for holders of specific tickets, 3rd-party polling apps can send out custom live event polls to users, and more! We are very proud of this, and excited for what may come in the future. We are also looking to spearhead this with the introduction of a gated GENESIS club for early supporters of the platform, where we will also release a template source code for other projects looking to achieve something similar.
To see our platform in action, we have created a few handy walkthrough guides for event organisers and ticket buyers, to help them with using this new technology. You can watch them here on our Youtube channel:
- How to log in with Metamask on mobile, and scan and stamp a ticket
- How to purchase an NFT ticket
- How to create an event on TKETS
III. Design and Implementation
Our code is accessible to anyone at our Github linked in this submission. Here, we will only discuss significant or interesting implementation details and challenges.
NFT Minting
Most users are unfamiliar with how blockchains and smart contracts work. Therefore, we created an event creation tool that was powerful and customisable, yet user-friendly and accessible to most of the public. There is no coding required at all, and the process is made to be similar to other ticketing platforms such as Eventbrite. The idea is for the user to simply input information about the event, and design their tickets with a piece of NFT media themselves, and then we will handle everything automatically, from uploading the media and metadata to IPFS, to deploying the smart contracts on the blockchain. Our smart contracts come in two parts, the EventFactory
and Ticket
smart contracts, and the source code for both can be found here.
The EventFactory
is responsible for keeping track of on-chain event metadata such as the start and end times, as well as ownership information for each event to handle ticket funds withdrawals. It is also responsible for mapping each event to their respective Ticket
smart contracts, as well as having a validateTicket
function that we use to check if a ticket is currently valid (discussed later in "Ticket scanning").
Meanwhile, the Ticket
smart contract represents the actual TNT721 NFT token. Each event can have multiple Ticket
smart contracts for each different ticket type. Each Ticket
also has a contrained mintTicket
function, which allows the buyer to mint a ticket directly to his wallet address if all the requirements are met (e.g. the amount sent matches the ticket price, the sale has started and not ended yet, the tickets have not all sold out, etc). The Ticket also has a stamped
boolean mapping from each ticket ID to check if a ticket has already been stamped before, used for live events where re-entrance is limited.
All of this functionality is then exposed to the user via an intuitive and clean user interface.
Graph Node Indexer
The next challenge we faced was how to index the events from the Theta blockchain in a scalable way. Querying the blockchain for logs each time is certainly not viable, and highly inefficient. It is also not viable to simply listen to events on a fixed list of smart contract addresses (like how most other NFT projects are able to), because our platform allows users to mint smart contracts dynamically, and therefore this list will change each time someone creates a new ticket. With some advice from Jieyi, we decided to look into using a Graph node indexer as part of our backend. As far as we know, this is the first working implementation of a subgraph on the Theta Network.
Since Theta Network is an EVM compatible chain, the graph node indexer was able to work almost perfectly without any modifications. There was a problem with the RPC server timing out when retrieving logs for 1000-block intervals, but this can be fixed by setting the maximum block range in an environment variable. The source code for our subgraph can be found in our Github repository. With the graph node indexer, not only were we able to more cleanly maintain events from all the smart contracts minted from our platform, but this also makes initialisation and error recovery much less messy. Since each graph node can be spun up without needing knowledge of any prior state, this also allows for a more scalable architecture, outlined in the System Architecture section.
If you would like a try out how the Graph node querying works for yourself, you can visit our GraphiQL interface here. Then, you can try entering the following query (or construct your own using the entity mappings in the GraphiQL interface and by referring to the Graph node documentation):
query {
ticketTokens (where: {ticket: "0x82bc05813ba10bdc12a469c3473104db1bcfcbfd"}) {
tokenID,
owner {
id
}
}
}
The above query lists the wallet addresses and token IDs of all the current holders of our EARTH NFT tickets, which has a smart contract address of "0x82bc05813ba10bdc12a469c3473104db1bcfcbfd". This information can then be used to conduct raffles, send airdrops, or even be queried by an application to provide gated access.
Ticket scanning
Next, we needed an interface for event organisers to securely verify tickets at the door, for live events. For this, we wrote a validateTicket function in our event factory smart contract. This function takes in the event ID, the ticket smart contract address, the token ID, the owner address, as well as a signature containing all the previous information. Then, we are able to first check if the owner indeed holds the specific ticket for an event. However, we are still not sure if the person who supplied the information actually has access to the owner address. Therefore, to ensure this, we also check the contents of the signature to see if it matches the sent parameters, and use ecrecover to verify the wallet address that signed it. If all of the information matches and the signer is indeed the ticket owner, then we know that the person presenting the information is a ticket holder, since the only way for them to obtain the signature is to know the private keys of a owner wallet address. Finally, we also include a timestamp in each of the signatures, and check if it was signed within the last 60 seconds, which provides another layer of protection. The arguments to the function call as well as the signature is abstracted away as a QR code or Base64 encoded text data on our web app, which event organisers can scan to easily call the validateTicket function on the blockchain.
Payments and refunds
For payments and refunds, we designed the system such that funds made through the sales of tickets can only be withdrawn after event completion. When an event is cancelled by the event creator, he will not be able to withdraw any funds even after event completion, and ticket holders are allowed to directly exchange their NFT tickets for the price they paid for each ticket.
Event dates are also immutable and cannot be changed. It is only possible to therefore cancel an event and create a new one. This is to reduce the amount of event fraud that might happen, and allow full refunds should an event be cancelled. We wanted to avoid the case where an event organiser already withdrew funding, but needs to cancel the event and fails to deposit back the full amount into the smart contract. This also makes for an interesting future development, where event organisers are able to stake assets (wrapped ETH, wrapped THETA, etc) to withdraw funds early, so as to better finance the event. Should the event be cancelled and the event organiser fails to repay the necessary funds, these can then be liquidated, such as in decentralised borrowing Dapps.
System Architecture
For our system architecture, we tried to design this in a more easily scalable manner. All of our backend services are dockerised, and both the application server (which stores part of the off-chain metadata) and the Graph node indexer (which handles on-chain events) are stateless, and store information on a PostgresDB hosted on AWS RDS. Therefore, should demand for the platform increase, it will be trivial to deploy multiple instances of both servers, behind a load balancer. Auto-scaling can then be easily set up to handle variable load spikes. The diagram below shows what we are scaling our architecture towards. Currently, both the application server and graph node are operating on the same machine (since load is not too heavy at the moment), but they are run on independent containers and can be easily separated to manage the load for both services.
GDPR and the issues with full decentralisation
Finally, our last challenge was regarding the compliance of privacy laws (such as GDPR), in relation to designing a fully decentralised application. Part of the GDPR states a right to be forgotten, which means that private information of a person should be able to be removed from the internet under certain circumstances. However, in the case of fully decentralised systems such as blockchains, this is impossible to achieve, since information is shared amongst all participants, and not held by a single entity. Therefore, even though we wanted TKETS to be as decentralised as possible, some information such as the event location and description are deemed to be too sensitive to be stored permanently on IPFS. Therefore, we store part of the metadata on a central PostgreSQL database, which can be deleted if the user requests to. We will also unpin any metadata files on IPFS upon request, and these files will be "forgotten" if no one else is pinning them. However, if they are, then the data is no longer held by TKETS, and we can no longer control how to remove them. We also let users know the implications of using the platform, so they are fully aware of any privacy risks involved.
IV. Lessons learnt
From building TKETS, we learnt that actually, implementing the technology is the easier part. The more difficult part is ensuring mainstream users know how to use the platform properly, as well as complying with the various laws and regulations. We also learnt how awesome and collaborative the Theta developer community is, with special thanks to Jie Yi for helping us along with our Github issues. We are working with other projects to not only support our TKETS NFTs, but also help them get set up with things like using a Graph node indexer for their own platforms.
We have also launched our GENESIS tickets with great success, and many positive feedbacks on the speed and clean user-interface. Some users were unfamiliar with Metamask, so we have created a series of video walkthroughs to demonstrate how our platform is used (linked previously). However, after getting past the initial learning curve, most users were able to navigate and make use of the platform's functions with great ease.
We have also learnt to be more keenly aware of malicious actors in our community. A few days after the platform launched, there were already several "scam" events popping up on the website. While this may be a twisted nod to how simple the platform is to use, it also posed a great danger to our reputation and trust in the community. Our team acted very quickly to warn users against these events, and swiftly removed them from our backend server. We also implemented a few changes, including a warning message to inform people of the permissionless nature of our platform, as well as a verified badge for trusted creators. Fortunately, we have not seen any more of such events after these changes. In the future, we would certainly make more efforts to understand any potential malicious uses of our features, and guard against them ahead of time.
V. Future plans
In the future, we plan on first of all, working with the community to launch more events on the TKETS platform. We have already contacted some streamers, such as HighsGamingHub, who have expressed great interest in our platform and supported us greatly in their community efforts. Some conferences have also contacted us about the us of TKETS for their events, although they are concerned about having to pay with TFUEL, with no options for other assets such as stablecoins or card payments. This is another direction we would like to take in the future as well. The current implementation also does not deal with ticket scalping, although this is a feature we would also like to add, to limit the number of tickets that can be bought per transaction, and to limit the number of tickets held per wallet address. We have also introduced the GENESIS club, which will serve to spearhead advances on the TKETS ecosystem and act as an template for other developers to build on. Finally, we would also like to transition the project into a DAO structure, with a native governance token on Theta Network. We hope that the community will embrace this project with open arms, and look forward to seeing more community-led events soon!
References
Built With
- django
- graph-node
- graphql
- postgresql
- react
- redis
Log in or sign up for Devpost to join the conversation.