Hello, friends! This past Sunday, after a solid year of coding during the pandemic, I released Hodlberg to mainnet.
The tl;dr: Hodlberg ]-[ Financial lets one “attest” their cryptocurrency holdings (across multiple blockchains) and mint an NFT. The NFT is non-custodial and compiles all attested wallet balances, ERC20s, and other held NFTs into one convenient token, without compromising privacy. The balance and token data aggregated into your Hodlberg NFT is live and always up-to-date. Of course, there’s a visual representation of all this (it’s an NFT after all), but the real magic is in the metadata and accompanying API.
The image above of the Hodlberg NFT is LIVE. Its underlying metadata was updated when you viewed it just now (pending any forum caching). It’s a testnet token (hence ‘T’ at the top), so don’t get too excited about my balance.
This is an atypical use-case for NFTs given the current zeitgeist, but the first notion I ever had about the ERC721 standard was in-game assets… something functional and unique. Hodlberg grew out of a desire to build a non-fungible token that was useful, transportable, auditable, and “fuzzy” – in more ways than one. Hodlberg has use-cases across gaming, social, finance, and the internet at large!
The contract’s tokenURI()
method returns a public endpoint rich in metadata, and an additional layer of authenticated calls via the API can return private-by-default holder-controlled details about the underlying assets.
There’s a lot more going on that I won’t bore you with here, but if you’re interested, the FAQ is a great place to start.
I come from an ecommerce and full-stack developer background (I’m also old AF), so Solidity hasn’t been too much of a stretch for me wrangle, but I’ve spent a lot of time on the OpenZeppelin forums, in the documentation, on StackExchange, and in various Discords learning the new tools used in Web3 development. It’s been quite a journey and I thought I’d take a moment to describe how the OZ contracts-upgradeable
and hardat-upgrades
comes into play.
The Hodlberg contract is extremely simple, but almost all of that simplicity is owed to the inheritance of the openzeppelin-contracts-upgradeable package, and specifically the ERC721PresetMinterPauserAutoIdUpgradeable.sol
template.
Upgradeable contracts are a controversial feature as they can essentially throw immutability out the window, but in Hodlberg’s case, where the NFT acts as the gateway to data stored off-chain anyway (in order to keep wallet addresses private), it seemed a reasonable design pattern, for now.
The original design of the Hodlberg contract included methods for storing and retrieving an on-chain “hash” that would help with auditing attested wallet addresses and data. As gas prices increased over the Summer, however, this approach became unfeasible. The decision was made to leave the entirety of the contract upgradeable so that, in the future if conditions improve, the hash feature could be added back, while also giving Hodlberg the most room possible for growth.
The AutoId
functionality is not used. Instead, we’ve opted to generate tokenId
with a hashing function, since the mintToken()
method relies on a “ticket.” The “ticket” is the UUID of the completely free, un-minted, “Temporary Token” created prior to minting. This temporary token only lasts 24 hours and doesn’t have many of the features associated with the minted NFT, but it’s a great way to test things out (there’s also a full-on Testnet implementation of the site and contract, of course).
Testing with openzeppelin-upgrades
in Hardhat was important to make sure our <uint32> tokenId
could be upgraded in the future as <unit64>
to return larger numbers should we need the space. Good (and, frankly unlikely) problem to have, but it’s nice to the upgrade patterns allow this to happen easily.
Additional new features include storage for the NFT’s “originalOwner,” supporting methods to retrieve that data, and the OpenSea recommended contractURI()
method, which points to an endpoint returning overall NFT collection metadata.
As previously mentioned, this contract is simple, and I don’t pretend it’s anything magical. That’s completely ok, however, because OpenZeppelin’s libraries allowed me to quickly enable immutable blockchain storage, interface with the ERC721 standard, and provide a fail-safe through an upgrade path if I missed something in the initial systems design. The bulk of the development time for Hodlberg was spent on the backend, the infrastructure, and the usability patterns. OpenZeppelin allowed me to move quickly from proof-of-concept to functionally live with a bleeding-edge technology, without having to claw my eyes out.
If you’re interested in learning more about Hodlberg, please check it out at hodlberg.com, or reach out to me on Twitter at @eviljordan or @hodlberg. We’ve also got a brand new subreddit.