CryptoTix is a ticketing system that can issue tickets to users who fit the rules set by event holders. It’s a web app I made in Nov 2022 with Blitz and Moralis for participating in a hackathon hosted by Shopify. In this post, I’m going to share something I learned from the development.
It’s a screenshot that show how will event holders create their event. In this screenshot, an event holder can pick the event name, a password, chain (one of those supported by Moralis), and the rules. The rules is composable, for example, I can limit only people who have 500 DAI and a ENS can issue a ticket.
First try at Blitz
In this project, I chose Blitz as the app framework. I knew it when I was exploring Next.js frameworks with ORM months ago, and I decided to give it a try since I need a database to store events. The ORM in Blitz is Prisma, it’s quite powerful for quick development. I only need to modify the scheme file and run some commands, it will generate migration files for me. When I was developing with Laravel, I spent a lot of time writing migrations. A fly in the ointment is that the down migrations (rollbacking modifications in database scheme) are a bit complex for me, hence I flushed my local database twice. Overall, I like the development experience in Blitz, I’ll be happy to start the next project with it.
An obstacle of verifying users’ asset
The goal of this hackathon is to verify users’ assets. It’s easy for ERC-20 and ERC-721 since both of them have the method
balanceOf, rules that require users to have an amount of token/collection are easy to implement. For ERC-1155, it’s harder than I expected. ERC-1155 also provided a similar method, but it requires the caller to list token ids, hence rules that require users to have an amount of ERC-1155 collection are hard to implement. Thus, I adopted Moralis API as an indexer to do the stuff. Moralis API will list all tokens a user has and their amount, the rules are then implementable.
Besides, Moralis API also shows when a user received NFTs, hence the hodl rules are implemented by the way.
Most interesting feature – Composable rules
The most interesting feature is the composable rules, it provides a semantic editor for event holders to configure the issuing rules. I came up with this idea at the very beginning but didn’t find a way to implement it. (Since I am very lazy, I was looking for a library to help me to make it.) I decided to delay the feature since it was almost the deadline for submission. I finished other features (scanning, ticket cutting, etc.), and found I still had a lot of time, so I started again.
Although I didn’t find a simple tool for it, I knew the keyword is
Condition Editor, and it would perform like a rule engine. (I still am not sure if it’s a kind of rule engine.) I found some designs from dribbble and imagined how it would fit into this project. Then, started coding.
The idea was: The rules are defined as serializable objects (hence they can be stored in a database and recovered from it), and there will be many kinds of rules. Two logic rules are AND and OR (other logic gates aren’t considered to keep it simple), and they accept an array of rules. According to this idea, I implemented a class to execute a rule, which will act according to the rule type, then the rules interface and implementation are trivial.
Now it seems not too hard to implement, thus I’m a bit curious about why there’s no library for it. In my opinion, it’s valuable for internal tools, no-code, low-code service.
Encryption and Decryption
Another feature I put some effort into is encrypting and decrypting a ticket. The idea behind this is that a user may like to issue a ticket from a device that ze doesn’t like to bring outside. However, sending a message (the payload of the ticket) might be dangerous. If a user simply saves zir ticket, the ticket may be uploaded to Google Photos, iCloud, or somewhere. The scanner may record the scan result. There are too many ways to leak, so how can we protect the ticket been stolen? My idea is simple: encrypt, transfer, and decrypt right before cutting. The user will encrypt the ticket with a password, hence anyone who gets the encrypted ticket can not use the ticket directly. The user then decrypts the ticket only when ze wants to use it.
This project let me learn a lot, and there are still a lot of things I haven’t tried. If I have more time, I would like to refactor the rule engine. Another thing to improve would be the design, I am really bad at designing, hope someone will release a tool for design idiots to build beautiful UI.