This is a proof-of-concept implementation for the GeoPass project. The GeoPass project has just been an idea and a research focus but nothing has been built... until now.
Learning about the capabilities of the Sony Spresense it got my gears turning on how to make GeoPass more real. I thought the Spresense would be the perfect platform for a trial implementation. Along with the Hackster.io competition (this project was submitted), I had a nice set of constraints to work with to help me really focus in on what the GeoPass project could be if it was actually built.
Since the GeoPass project is a rather large sprawling concept involving citizens, cities, and local businesses for this initial build I really slimmed it down. I hope what I have here is a minimal viable product and something you can and would want to build too!
This project contains all you need to build, configure, and deploy your own geoLocation based cryptographically secure token airdrop device and backend supporting service. If that is confusing... read on.
Token Towers: Concept ImageSmart cities are more than just sensors and monitoring. To truly succeed they need to address the privacy concerns of the citizens. Our "smart cities" should not be just a friendlier name for government surveillance. There should be a balance of information where the citizen has a say in what is collected and how it is used.
This project is a novel approach to try and balance privacy and citizen engagement. The goal is to create an end-to-end solution that can be adopted at any level, individuals, organizations, businesses, governments, etc... It's an open and extensible framework.
For this project, you will be creating a "Token Tower" device and back-end system. This is the DIY version. Lots of corners were cut and it is by no means battle tested. But if there is more interest a production ready solution could be built using this project as the foundation.
What does this do?In short, this project lets you send ERC20 tokens to people based on their physical location without their location being stored on the blockchain. The backend service, blockchain smart contracts, and Spresense IOT device all work together to deliver "Community Tokens" to citizens who scan their wallets at approved "Token Tower" token granting devices that are installed in areas around cities, such as parks, venues, free events, etc...
Why would I want to do that?Well, incentives really. If you want to encourage people to go to a place you can create some kind of rewards program. It is pretty common at just about every business on and off-line. Think punch-cards for sandwich shops but applied to every square inch of the planet. This project lets you create a trusted, secure, open source and potentially interoperable (universal even) rewards program. Visit a place, scan your wallet, get tokens.
The first step of any rewards program is setting up the cool rewards that get people interested. But the second part is the boring accounting. This is where blockchains shine. They are a very durable and verifiable way to do accounting. The problem is that they're entirely public. A rewards program on a blockchain would let everyone see how many points you had, and also everywhere you got those points (or "Community Tokens" in this case).
What does this have to do with Smart Cities?With a project like this, you can create a city/county/country wide program to encourage the use of public (tax paid) commons (without the tragedy part). You would define the areas where citizens could earn points (aka tokens) by visiting, deploy a set of "Tokentower" devices, then let citizens collect a token for each visit. The actual use of these tokens to say, redeem a free paddle boat rental at the lake in the park is outside of the scope of this work (but it would be a perfect use case).
The low power, on-board capabilities of the Sony Spresense chip (such as GNSS, and LTE) make it possible to run this project entirely off of solar power. Cities could deploy hundreds of these devices to any location or point of interest where citizens would like to earn Community Tokens.
Why Token Towers? Don't we all have smart phones?Well, yes most of us have smart phones. But there's a few reasons why you would not want to rely only on a citizen's mobile phone. First reason, is that you need an app. Those come with their own privacy and security issues. Plus you have to design, build, test, and support a wide variety of devices (*cough* Android *cough*). Also, there are really just two companies that control all of the software that run on mobile devices (Apple and Google). Second reason, you might not want to trust that GPS information on a phone is that it can be faked. Granted there are various levels of effort required to spoof your location but it could be done if someone was sufficiently motivated. Third, (and probably most importantly) you actually don't need have a smart phone at all to participate and receive the Community Tokens. You could scan a print-out of your wallet's QR code and you'd still be able to participate in the community rewards. Everyone wins!
What are the major parts of the project?The high-level components are:
- An EVM compatible blockchain and smart contracts to manage the accounting side of the tokens (Implemented on Polygon)
- A supporting webservice to provide an API for the hardware device (API implementation uses Cloudflare workers)
- A privacy preserving ZeroKnowledge cryptographic framework (Circom ZK framework and custom ZK circuits for a particular GPS region)
- A trusted hardware GPS/LTE/Sensor device (Sony Spresense IOT hardware device)
All these components work together to create a seamless end user experience claiming a custom token with out sacrificing their privacy.
As someone looking to deploy and use this project, for this particular implementation, you would need the following:
- A Cloudflare account (free version is fine)
- An Infura account (free version is fine)
- A Sony Spresence hardware device (and all the components detailed in the hardware section)
- A specific geographic location in mind for deployment/testing
- TruPhone account (or similar) for HTTPS access
- A wallet with some test Polygon MATIC on a test network (such as Mumbai)
The technologies use here are:
- NodeJs - For the webservice backend
- Solidity - For the smart contracts deployed to the EVM compatible blockchain
- Circom - A ZeroKnowledge framework to create Groth-16 based ZK SNARKS
- Various web service/SAAS providers mentioned above
This is an advanced build. You'll need to have some knowledge of hardware, web services, and smart contract deployment on blockchains. Drop a comment on the project if you have any questions and I'd be happy to explain.
Please note that the github repos contain a lot more information for the backend services than what I described here. Check out the README files in there for setup, dev, and deploy steps
HardwareThe hardware might actually be the easy part of this project. ;) You'll need to purchase all the hardware components and allow for any issues or availability of the parts. You will also need to 3D print the enclosures in the attachment section. The 3D printed parts are designed to snap together but your milage may vary here, depending on the printer you use and how accurate it is.
Once you have the 3D printed parts you can wire and install all the components. Note that custom cut-outs in the base are for the Sparkfun QR code scanner, and the Adafruit funky triangular sci-fi button.
FirmwareFor the firmware you'll need to clone my fork of the Spresense SDK and then follow the commands in the README for the lte_http_post project (I will be renaming this soon). This should allow you to configure and build the Nuttx package you'll flash over to the device. Also, note you'll need to make sure you configure the APN in the project config settings (graphical menu). Also, Also,... if you're on TruPhone you should follow this post to make sure your SIM card is activated.
MiddlewareLook in the mono repo for the validator-service-api folder. This is where the web service API code lives. Instructions are in the README for installation. For the least friction I suggest you deploy to CloudFlare as a worker using their Wrangler package. But the code is pretty straight forward so you can deploy anywhere you like that supports NodeJS.
BlockchainIn the repo, the contracts folder contains the smart contracts for deploying to the Polygon network. I used Hardhat to manage the deployment and it's supporting scripts really help with this process. The ERC20 tokens are based on OpenZeppelin standards and have minimal changes. Instructions for deploying to the Polygon Testnet are in the folder README.
Zero KnowledgeThe ZK component in this project is important to preserve the end users privacy. It is based on work found here in the ZKMaps project. But essentially, you define a "circuit" in the Circom DSL and then compile your proving artifacts from there. For this particular Groth-16 style proof there is a "trusted setup" phase you'll need to go through once (instructions are in the Circom library). This creates the cryptographic artifacts that are then used to generate your witness file (the proof that you have the information you say you have, in this case GPS coordinates that fall within a region), and the Solidity contract that will be deployed to a blockchain along with your ERC20 contract. The generated ZK solidity contract will validate the input provided by the middleware webservice before the end user is granted a token. This is the critical piece to the project to both prevent fraud and also preserve privacy.
The Circom circuit contains the boundary definitions for the geographic area where you want to reward tokens. Right now it only supports rectangular areas but there is work being done to support arbitrary non-overlapping contiguous shapes. This would make it much more useful since most outdoor spaces are not rectangular. Check the circom-circuits folder for the READme, build scripts, and more details.
Project Status: Work in ProgressThis project was put together for the Sony Spresence developer challenge. Here's what has been completed:
- Concept, design, and architecture of final prototype system
- 3D designs for enclosure to house the solar panel, battery, interface elements, and Spresence LTE board.
- Created, tested, and deployed initial version of validator-service-api to CloudFlare
- Created, tested, and deployed locally ERC20 contract to manage Community Token grants to user
- Created initial project/app in Spresence SDK and built simple http_post project to call Webservice over LTE and POST sample data
What's left...
- Implement the changes to the Spresense firmware to trigger scanning of the QR code when the scan button is pressed. (optionally, play a sound during scanning/ validation process)
- Change the HTTPS POST body to the Webservice API to include the QR string value, along with the GPS coordinates taken from the Spresence board
- Implement the API changes to take the address/coords and generate a ZK witness and on-chain call parameters to submit to the on-chain Smart Contract
- Update ERC20 contract to call ZK validator contract before granting tokens, update deployment scripts to deploy both contracts together
- Update documentation to show end-to-end build, how to configure for yourself and how to deploy the system
- Deploy and support community versions of the webservice API and ZK validator such that people following these build instructions can focus on just the hardware side, and less on the operations side of the backend systems.
While there was ample time for the contest, I hit a few significant challenges along the way. The most negatively impactful issue was my initial plan to use Circuit Python for the firmware on the Spresence board. As it turns out, there are many core modules in Circuit Python that are missing from the Spresence build (like LTE support). I spent too much time trying to build and fix missing modules in Circuit Python. Once I realized I needed to abandon this path and build my app in C in the CLI environment, using the Nuttx build tools, it was too late. While I have experience in C and embedded development I don't have experience in Nuttx or any of the build tools and processes used in the Spresence SDK. For what it's worth, the SDK has all the examples I could want, and fantastic build tooling. In a short time I was able to accomplish a lot. But in the end it was just too much and too late for me to skill up on while completing the rest of the other non-hardware components of the project. I intend to continue this work and update the repos/this description as I progress. Watch this space! And consider joining the project and helping out if you too see the value.
Comments