How We Created A Truly Trustless FLT Rewards Program
The long-term goal for Fluence has always been to foster a vibrant community of developers and users who believe in our vision. Our community rewards program, through which we have allocated FLT-DROP tokens to more than 110,000 GitHub accounts, was a call to action for developers around the world to join us in building the future of decentralized technologies.
It was important for us that our method for distributing FLT-DROP tokens reflected the ethos of our protocol: it needed to be fully decentralized and truly trustless. How could we say that decentralization is at the core of our project if the way we distributed tokens to developers relied on centralized methods vulnerable to manipulation and poor security? With this in mind, we built a truly trustless claiming process, taking inspiration from the Handshake’s method.
First, we collected the GitHub handles of contributors to the best projects in Web3 from a list by Electric Capital and built a mechanism for these users to claim FLT-DROP tokens as a reward for their work toward building Web3. Then, we set up a process for the eligible developers to claim their FLT-DROP tokens where they decrypt the private key for a temporary Ethereum wallet with their GitHub SSH key. We have limited claims to 50 million tokens, with the number of claimants decided by the claim rate and the resulting halving.
For users, the process is as simple as checking whether their GitHub account is on the eligibility list, using their SSH key to prove they own their GitHub account, and selecting a wallet address to receive their tokens.
All this is done offline and on their own machine, with the source code is written in a way to be readable and verifiable, meaning claimers can see for themselves that their SSH key cannot be exposed at any point and security is upheld. Furthermore, the process avoids using centralized authorization tools like GitHub OAuth, meaning that it cannot be controlled by whoever might gain access to the OAuth oracle and is essentially unhackable. At its core, this process is secure, not open to manipulation, and fully decentralized and trustless. We hope that it can serve as a model for distributing token rewards by projects across the industry.
See below for an in-depth outline of how we at Fluence set up the process and how users can claim FLT-DROP rewards.
Setting Up the Process
Step 1: Temporary Wallet Generation
The first step was to generate a temporary Ethereum wallet for each GitHub account identified to receive a reward, then encrypt the private key of that wallet for each public SSH key from GitHub. For this encryption, we used a tool called Age, which enables us to encrypt data for public SSH keys to be decrypted with private SSH keys.
After this step, a map of encrypted Ethereum wallets was produced to a file named metadata.json
. Anyone can download this map, but only the holders of the eligible SSH private keys can decrypt their associated temporary Ethereum wallets.
Step 2: Merkle Tree Generation
In addition to the metadata.json
map, we have also generated a Merkle tree with the addresses of the temporary Ethereum wallets and put this on the Ethereum blockchain. This made it possible for our smart contract to tell whether a particular wallet belongs to the set of temporary Ethereum wallets.
Step 3: Contracts Deployment
Finally, we deployed the contracts for the token distribution. Each contract can be viewed here.
How User Claim Works
To claim their FLT-DROP reward, users are required to complete a few steps to ensure the process remains secure and trustless, with the source code fully transparent and verifiable, and the whole process completed on their machine by decrypting temporary Ethereum wallets in a json file with their SSH key.
Step 1: Eligibility Check
When a user wants to claim, they first need to look into the metadata.json
file to see if it contains their GitHub handle (this can also be done by simply entering their GitHub username on this page). If it does, they can proceed to the next step.
Step 2: User Chooses a Wallet To Receive Reward
Before generating the proof, the user needs to select the Ethereum wallet that will receive the FLT reward. For the purposes of this guide, our user is called Alice and she wants to receive her FLT reward to a wallet called 0xAliceMainWallet
.
Step 3: User decrypts the Temporary Ethereum Wallet
To generate the proof, Alice first needs to decrypt the Temporary Ethereum Wallet from the metadata.json
file.
She filters entries of the metadata.json
file, and takes these that contain her GitHub handle. Then, she tries to decrypt each of them with her SSH key of choice. That way she obtains the private key for the Temporary Ethereum Wallet, let's call it 0xAliceTmpWalletPrivateKey.
Step 4: User Generates a Proof
To generate a proof, Alice signs 0xAliceMainWallet
with the private key of the 0xAliceTmpWalletPrivateKey
, and generates a Merkle Proof for the inclusion of 0xAliceTmpWalletAddress
into the Merkle Tree of all Temporary Ethereum Wallets.
By completing these two steps, Alice has enough information to prove that:
- She has access to the SSH private key associated with her GitHub account
- She intends to send the reward to 0xAliceMainWallet and nowhere else
- Her Temporary Ethereum Wallet is on the list of temporary wallets created by Fluence to receive FLT-DROP rewards
The final proof format is defined as follows:
# userId, tmpEthAddr, signatureHex, merkleProofHex
"${USER_ID},${TMP_ETH_ADDR},${SIGNATURE_HEX},${MERKLE_PROOF}"
USER_ID
is just an index in the metadata.json that’s used to check if the user has already claimed the tokens.
Step 5: User Sends Proof
Now, all that Alice has to do is send the proof to the smart contract, which she can either do manually or pasting the proof to the claim website.
Step 6: Proof Verification in the Smart Contract
After proof is sent, it is verified in the reward smart contract. This happens in three steps defined in the reward contract code:
- Check if the USER_ID has already claimed
- Check if the TMP_ETH_ADDR belongs to the temporary Ethereum wallets set
- Check if SIGNATURE_HEX is correct and was made with the intention to send tokens to msg.sender
By creating a way for users to claim their rewards using off-chain SSH verification and without running through centralized GitHub infrastructure, we have maintained a truly trustless and decentralized pathway to reward those building Web3. We hope that this process can serve as a model for distributing token rewards by projects across the industry.
We want to thank those who have already claimed their FLT-DROP and welcome you into the Fluence ecosystem!