At MakersPlace we’re building a platform that enables digital creators to create and sell unique digital creations as non-fungible tokens on the blockchain (learn more here). An important part of selling a unique and limited edition creation is ensuring the authenticity of a creation and the proof that it was created by the real creator. We’d like to share what we built to solve this at MakersPlace.
Why is Identity important?
When you’re dealing with the sale of high valued creations it’s important to validate the identity of the creator. This ensures that buyers are purchasing the authentic creation by the legitimate creator. Identity is also crucial to establishing trust with customers. We see this with services like Twitter, which provides a verification service to establish trust between users and what they say, once a user has provided the necessary personal documents.
Although identity verification is a common problem already solved by services like Twitter, our goal was to build a decentralized identity solution. The reasons being:
- We don’t want to store sensitive user identity data in a central location, to avoid large-scale breaches.
- We want identity claims issued to a user to persist even if MakersPlace no longer existed.
Finally, we need to validate a user’s identity in a privacy-forward way. For example, let’s say J.K.Rowling is selling a digitally signed copy of her e-book. As a buyer I want to make sure that the signature is authentic. We could publish her government ID and other personal identifiers along with her signature, but that’s not ideal. Instead we need a way to validate and store her identity in a privacy-forward way, along with her signature on the e-book.
Solutions We Evaluated
Unfortunately verifying identity in a decentralized manner is still very early and we had to evaluate a number of service providers and solutions. We first looked at Civic and uPort’s decentralized identity services.
The Civic Secure ID Platform provides secure identity verification through a user’s mobile device. Through the Civic app, a user can take a picture of their government-issued ID and verify their identity within seconds. The unique thing that Civic offers is that each user’s data stays on their mobile device, making sensitive user data decentralized. Every time a user verifies their identity through Civic they need to authorize Civic to provide their data from their device. Even if Civic gets compromised, there is no user data to be compromised. This is unlike a traditional identity platform, where the user’s data stays with the platform and a compromise leads to widespread loss of user data.
uPort is another identity system which operates in a decentralized manner. uPort also provides a mobile app similar to Civic but found that although they had built a really great lightweight identity standard and platform, the user experience wasn’t as polished and was still undergoing changes. As a result we had some difficulty navigating their documentation and didn’t find enough user adoption compared to what we saw with Civic. That being said, uPort recently standardized their identity smart contracts under ERC-1056, which turned out to be really helpful. We’ll share more thoughts on this later in the post.
While Civic and uPort both offered decentralized identity verification platforms, our specific use case required more. Specifically, the ability to store verified identity claims on chain and associating them with a user’s blockchain ID (e.g Ethereum address). To address this, we looked at a number of blockchain identity standards.
ERC-725 and ERC-735
The first set of identity related standards were ERC-725 and ERC-735. While 725 is a full-fledged identity standard using private keys to sign actions like login and identity claims, 735 manages identity claims. The biggest challenge we identified with 725 was that every user account requires an identity contract to manage their identity. This becomes expensive since you need to deploy a separate contract per user to manage their identity. Although it offered what we needed to verify and store identity claims on chain, it was too heavy-handed.
When we evaluated uPort we also researched ERC-1056, their lightweight identity standard. What’s great about 1056’s approach is the Ethereum contract is effectively a key / value store and automatically supports any Ethereum address to assign identity claims to. Each user can upload some identity data that pertains to their identity, which will persist on chain.
Our Solution (Civic + ERC-1056)
Civic — Decentralized Identity Verification
We decided to partner with Civic, and use their Know Your Customer solution to verify a creator’s identity. Civic’s mobile app experience is one of the best we’d seen, and the Civic team was very supportive and helped us along the entire way with our implementation. Most importantly, the guarantee that a user’s data isn’t stored beyond their device allows us to perform sensitive identity verification checks on our creators, while mitigating the risk of the creator’s personal data being compromised.
With our integration, creators can now visit their settings page and through their Civic mobile app they scan a QR code and provide any amount of personal data they feel comfortable with. On our end we verify the creators name, email and the fact that they’ve uploaded a Civic-validated government ID as a SHA-256 hash and store it into IPFS (a decentralized file system). Here’s an example of what that looks like:
"detailed_type": "Email Address. (e.g email@example.com)",
This identity verification now resides in a decentralized file store and can be validated by anyone who has the raw information, using the provided signature_type. (e.g SHA-256)
ERC-1056 — Decentralized Identity Claims
Once we’ve verified a user’s identity, we want to store the identity claims in a decentralized way. We decided to use uPort’s public ERC-1056 smart contract due to it’s lightweight implementation and native support for Ethereum public addresses. We now take the IPFS hash and write it to the ERC-1056 Ethereum smart contract, associating it with a creator’s Ethereum address.
At MakersPlace we manage all of our creator’s Ethereum wallets as a way to simplify their experience with the blockchain. This means we also manage the identity claims that get associated with each creator’s Ethereum address. To do this, we use ERC-1056’s ability to nominate an address that can manage another address’ identity on their behalf. In our implementation, we decided to nominate an Ethereum smart contract. We chose to nominate a smart contract instead of an Ethereum account so that we enforce strict processes when writing identity claims, through a well-tested and immutable smart contract. A well-tested smart contract also mitigates human errors and reduces the risk of an account being hacked, which would allow an attacker to write identity claims at will.
Interim Identity Smart Contract and Timed Delays
A key design pattern that we implemented with our identity smart contract is timed delays. Although we could immediately write identity claims onto the blockchain, we chose to add timed delays into every write operation so that humans can intervene and stop bad actors during this waiting period. To do this we implemented an InterimIdentity contract which houses the identity claim temporarily, for a human to review.
InterimIdentity Contract Interface
setInterimIdentity(address owner, bytes32 key, bytes value, uint validity)removeInterimIdentity(address owner, bytes32 key, bytes value, uint validity)flushInterimIdentity(address owner, bytes32 key, bytes value, uint validity)
Only after the timed delay has expired can the InterimIdentity contract write the identity data to the real ERC-1056 identity contract. Finally, we surface all verified identity claims directly to our customers as part of a digital creation’s proof of authenticity. Here’s an example of what that looks like.
Although MakersPlace manages our creator’s Ethereum wallets and identities, we also ensure that there’s a clear path to transfer ownership when someone no longer requires our services. With ERC-1056, when a user decides to take full ownership over their identity, we can verify their ethereum address and transfer the ownership of their identity to their personal Ethereum account.
Decentralized identity solutions are still early in its development but there are already great projects and solutions available. Our current solution solves our current needs using a decentralized identity verification service (Civic) and a decentralized identity claim holder (ERC-1056).
How can you use our solution?
As we keep pushing more identity data to the public ERC-1056 contract deployed at 0xdca7ef03e98e0dc2b855be647c39abe984fcf21b, you can look up any given address’ identity by parsing the DIDAttributeChanged events on the contract. Our key / value structures looks like the following:
We also open sourced our Civic Python Library that we built for our Civic implementation, since Civic only offers NodeJS support. Try it out and leave feedback.
If you’re interested in solving problems like this, we’re currently hiring engineers excited about empowering the world’s digital creators using blockchain technology.