Unlock is a protocol which enables creators to monetize their content with a few lines of code in a fully decentralized way, enabling programmable access to resources. This could include a blog, a subset of software features, or an event.
The core of the protocol is built on ethereum, and is enabled by 2 primary smart contracts,
Unlock.sol is the factory contract. it deploys locks for creators and is responsible for managing network-wide functionality such as granting discounts and tracking the GNP of the network. This contract is upgradeable.
Publiclock.sol is the lock contract. These are deployed by the factory when a creator creates a new lock. We don't actually deploy the full lock contract for each lock. This would be very heavy, as
PublicLock.sol is a large contract. (To get an idea of the size, when flattened it's about 3,470 lines of code). Instead, we make use of eip-1167 (minimal proxies) to deploy lightweight proxy-clones for each lock. The logic for these clones is determined by a single deployed
PublicLock.sol which acts as the template for all locks.
We make use of a number of the tools & libraries that OZ offers:
At Unlock, our approach to upgradeability has been to make the factory contract(
Unlock.sol) upgradeable to enable us to continue to add and refine features. Since launching, we've had many requests from users to add support for new use-cases and without upgrades, this just wouldn't be feasible. However, the Lock contracts deployed from this factory are NOT upgradeable. This gives lock creators assurance that their lock is theirs forever, and can't be changed by anyone.
While there's no shortage of debate over the very idea of upgradeable contracts in the industry, one thing is very clear; the Openzeppelin-SDK makes it super-easy to manage and track upgrades! We manage most contract deployments and upgrades of
Unlock.sol with openzeppelin's cli and appreciate the way the "network files" (ie:
/.openzeppelin/mainnet.json) help us to keep track of the deployed contract addresses, current implementations, etc. Also, the ability to deploy contracts and then query them or submit tx's easily all via the cli is nice, avoiding the need to jump back and forth between many different toolsets to achieve the same.
We use a number of openzeppelin's contracts from
@openzeppelin/contracts-ethereum-package/. These include:
We've only just started to use some of the OZ test-helpers, but the experience so far has been great. For those who haven't tried them, they make a lot of common, repetitive tasks in testing very straightforward, and I highly recommend at least checking them out.
We currently use
Ownable.sol and the
onlyOwner modifier extensively throughout our contracts. However, having realized some of the limitations/drawbacks of this approach, we've been re-evaluating our approach to access control and are migrating to a predominantly role-based approach using OZ's
Roles.sol. At the moment it seems that the current approach to this topic is being revamped by OZ, so we're watching to see what emerges and will have to reassess whether it still meets our needs.
To learn more or get in touch, feel free to reach out to the team, try out our dashboard on the rinkeby testnet, or just explore the code in our GitHub repo.