In early 2023, I was approached by a client with an interesting idea: a decentralized sports betting platform where friends could bet with each other using any cryptocurrency, maintain complete anonymity, and trust the system without a centralized authority holding their funds. He needed a proof of concept to validate the idea before investing anything on it.
His initial idea was to ditch the bookies, and directly bet with your friends, but after few brainstorming sessions, we evolved the idea into a more interesting product. The platform had two betting modes: open bets anyone could accept (like a market), and exclusive bets directed at specific users. My job was to build an MVP over six months that proved this could actually work on blockchain. The challenge was not just making it functional, but solving several technical problems that made similar platforms fail or become too expensive/difficult to use.
The Handshake Protocol
I called the core betting mechanism the Handshake Protocol, treating each bet as an agreement between two parties that gets enforced by the blockchain. A handshake has a simple lifecycle: someone creates it and locks their funds, another person accepts it and locks matching funds, the match happens, and the winner gets paid automatically.

The smart contract organizes everything around fixtures (sporting events) and handshakes (bets). Each fixture has a betting window and a result that gets updated after the match. Each handshake stores who is betting, what they are betting on, how much, and its current state.
When someone creates a bet, they choose between exclusive (only a specific person can accept using their wallet address) or open (anyone can accept). Funds lock immediately. If the other party rejects or never responds before the match starts, the initiator gets refunded. Once accepted, both parties are committed.
After matches finish, the contract resolves all bets at once in a batch operation, determines winners, takes a percentage as platform commission, and pays out. For draws or postponed matches, everyone gets refunded. The hardest part was not the edge cases where users try to game the system or transactions fail at the wrong moment.
The Multi-Token Problem and Tokenomics
The client wanted users to bet with any token they owned, ETH, USDC, SOL, BTC, whatever. But this created a nightmare scenario for the smart contract. If user A bets 0.1 ETH on team A and user B bets 150 USDC on team B, how do you determine the winner's payout? What if ETH price crashes between bet placement and resolution? You cannot fairly resolve cross-token bets without a stable reference point.
My initial approach was to integrate Uniswap directly into the betting contract, so every incoming bet would swap the deposited token for USDC at the moment of acceptance. The problem with this was gas costs (it was very high back then). Swapping tokens on Uniswap inside a contract call is expensive, and when you combine that with the handshake logic, bet placement was costing users huge amount of gas. That is completely unusable for small bets.
So, I designed a two-token system with an intermediary platform token. Here is how it works: users deposit any token into a separate conversion contract (not the betting contract). The Native Token contract uses Chainlink price feeds to calculate the USD value of the deposited token, then mints an equivalent amount of platform tokens to the user's wallet. The platform token is pegged 1:1 to USD via this minting mechanism, so it acts like a stablecoin but without the regulatory complexity of being an actual stablecoin.

Making it Gasless
Asking users to pay gas fees for every action kills adoption. When gas prices spike, a simple bet acceptance can cost more than the bet itself. The client wanted it to feel like a normal website where you just click buttons.
The solution was meta-transactions through a relayer. Users sign messages with their wallet instead of sending transactions. These signatures go to a backend relayer service that wraps them in real transactions and pays the gas. The smart contract verifies the signature and executes the action as if the user sent it directly. The user never pays gas, the platform does.

The security challenge was preventing the relayer from stealing funds or replaying signatures. I used nonces (incrementing counters) so each signature only works once, and added expiration timestamps so old signatures become invalid. The relayer is just a messenger with no special privileges, all fund transfers go to addresses recovered from the user's signature, not the relayer address.
The relayer is a simple Node.js service that validates signatures, simulates transactions locally to catch failures before wasting gas, then submits them to the network. For the MVP I ran it on a basic VPS. The platform pays gas costs but offsets this with the 10 percent commission on bets. Users can still interact with the contract directly if they want, but most people just use the gasless option.
The Oracle Problem
Getting sports results onto the blockchain was the hardest challenge. Blockchains cannot access external data directly, they need oracles. Chainlink is the standard, and they offer sports data oracles that aggregate match results from multiple sources.
The problem is coverage. Chainlink only covers major leagues like NFL, NBA, and Premier League. The client wanted smaller leagues and basically all sports. I checked alternative oracle networks like Band Protocol and API3, but coverage was even worse. Oracle providers focus on price feeds because that is where demand is, sports betting is still a small market.
I designed a hybrid system. Major fixtures use Chainlink oracles, fully decentralized and trustless. For everything else, we fall back to a manual oracle where a validator (initially the client) submits results. Not ideal, but I added safeguards: results can only be submitted after matches end, anyone can dispute a result by staking tokens, and all updates emit events so users can monitor for manipulation.

I know, the manual part undermines decentralization, but it was necessary for the MVP. The architecture supports transitioning to full oracle coverage as networks improve. I built a monitoring dashboard that compares submitted results against multiple sports APIs and flags discrepancies automatically.
Chainlink oracles are also asynchronous, you send a request in one transaction and receive the result in a callback later. This means match results and bet resolution happen in separate transactions, adding latency but keeping things decentralized. I added a fallback where the validator can manually submit results after 24 hours if the oracle fails, preventing bets from getting stuck indefinitely.
Testing and Launch
Testing on Ethereum Sepolia testnet revealed bugs that would have been catastrophic with real money. One early version allowed users to overpay when accepting bets, and the excess would be locked forever. Another version had a race condition where two people could accept the same open bet simultaneously. I wrote over 20 test cases covering normal flows, edge cases, and attack scenarios.
For the MVP, we deployed on Ethereum Sepolia and Polygon Mumbai testnets. The frontend connected to MetaMask and let users place bets, accept bets, and view results using mock fixture data. Gas costs on Polygon were 100x cheaper than Ethereum, making it the obvious choice for mainnet.

I set up monitoring to index contract events, giving us a queryable API for bet history, user activity, and platform revenue without constantly hitting the blockchain. The frontend used this for leaderboards and activity feeds.
Lessons Learned (Images are from the Protptype)
After six months, I delivered a working proof of concept. The client could show investors that the core idea worked: users bet with any crypto, the platform converts everything to a stable token, matches settle fairly, and no centralized party holds user funds. The handshake protocol handled hundreds of test bets without issues.

The biggest lesson was that blockchain development is 80 percent edge cases. The happy path is easy, the hard part is handling all the ways things can break. Users trying to exploit bugs, network congestion breaking oracles, tokens with weird behaviors, race conditions in concurrent transactions. Every state transition needs bulletproof validation.

Oracles are still the weakest link. Chainlink is great but has coverage gaps, and falling back to manual data entry undermines decentralization. If I built this again, I would spend more time securing sports data partnerships or designing a decentralized validator network with proper incentives.

The meta-transaction pattern worked well for user experience, but running a relayer is operationally complex. You need monitoring, reserves, gas price strategies, and graceful failure handling. For production I would use a service that already exists (even more than the time I was working on this project) instead of maintaining infrastructure.
The MVP gave the client what he needed for his team to complete the product. The core contracts were the foundation of the platform, though they have been audited and extended later. It was a challenging six months that pushed my understanding of smart contract design, tokenomics, and the practical limitations of decentralized systems.

Find More of My Works
Get in Touch
Ready to bring your ideas to life? Get in touch to discuss your project and see how we can create something amazing together.




