This is a three-part series on the basics of SBT, the vision for SBT, its technical implementation, and the possibilities of leveraging ZK technology. The goal of the series is to demystify the idea of SBT technology and provide an implementation to build a Web3 future with social identity integration. Part 1 discusses what SBT is and its basic characteristics (see Golden’s previously translated article “SBT Basics and Full Analysis of Potential Cases”). Part 2 discusses its underlying implementation and how to use SBT to add privacy. Part 3 will discuss how ZK technology can be used to improve SBT privacy.
This article, its second part, will talk about the implementation of SBT based on the design guidelines presented in the first part.
1. Implementation ideas
1.1 Comparison with NFT
1.2 Basic SBT
→ 1.2.1 Coinage and destruction
→ 1.2.2 Off-chain storage
→ 1.2.3 Verify SBT properties
→ 1.2.4 Update SBT data
→ 1.2.5 Basic use of SBT
→ 1.2. 6 SBT’s need for privacy
2. SBT with private data storage
2.1 Store data on-chain but hash addresses
→ 2.1.1 Example usage
→ 2.1.2 Discuss SBT with on-chain hash
2.2 Store IPFS etc. Off-chain projects of third-party providers
→ 2.2.1 Linking off-chain data with on-chain hash links
→ 2.2.2 Risk of off-chain secrets.
1. SBT implementation ideas
In this subsection, we discuss the implementation of SBT and its trade-offs.
1.1 Comparison of SBT and NFT
Now that NFTs and SBTs do sound similar, what are the key differences between these data structures in terms of implementation?
Unlike NFTs, which are designed to be tradable, SBTs should be soul-bound in nature and should be non-transferable.
The data of NFTs is public. However, the SBT project may wish to keep its data private.
Privacy can be achieved in a variety of different ways.
SBT’s data should be easily readable by other on-chain or off-chain projects.
Using SBT features as a guiding principle, we implemented SBT in Solidity. (https://github.com/SpartanLabsXyz/spartanlabs-contracts/tree/main/contracts/SoulBoundToken)
We will discuss our implementation in the following subsections.
1.2 Basic SBT
The base SBT can be used as a template for other projects wishing to build on SBT. The underlying implementation does not involve a discussion of privacy, which will be covered in Section 2 of this paper.
1.2.1 Casting and Burning
The contract is designed such that minting should be checked by the project owner. This is to prevent potential loopholes that a user can mint any SBT information, such as a user would mint a good credit score, but this is not the intent of the project. The idea is that projects should identify, validate and mint the correct data related to SBT.
Likewise, for the burning of SBTs associated with addresses, we also believe that users should not have the ability to easily delete their data, especially when that data contains a certain negative attribute. Users should be able to propose to burn their SBT, but the execution of the burn should be decided by the project owner.
Burn can be implemented for projects that wish to allow users the option to delete data. For example, if a user wants to delete all information from the project due to inconsistency with the project’s goals, he should have such an option.
Another consideration is that projects may want to manage their SBT communities and remove users if they violate their community management terms and conditions. For example, in a community that publishes SBT, there may be users who don’t follow the rules and behave inappropriately. Therefore, the community can decide whether to remove a user’s SBT from its project. Such communities may wish to further implement a suggestion mechanism to allow spontaneous suggestions to delete data or suggestions to burn other people’s SBT.
1.2.2 Off-chain storage
Data can be stored on-chain or off-chain. In our implementation, we assume that SBT’s data is stored off-chain, with IPFS as the supply side. In our implementation, the URI stored off-chain can be combined with an identifier in the data structure “Struct Soul”.
Projects are able to adjust the proposal structure depending on whether they want to store SBT properties off-chain or on-chain.
1.2.3 SBT attribute verification
Other counterparty projects should be able to easily retrieve SBT data.
This is useful for counterparties who want to verify user SBT attributes. Other projects will be able to check if an address has a soul bound to it, and verify the properties that soul contains.
This is important for the composability of SBT with different projects, other projects may want to interact and validate the user’s properties. However, users and projects may not wish to expose data, and there are ways to protect data privacy.
1.2.4 Update of SBT data
We don’t want users or other parties to update the soul, we want updates by licensed authorities because we want changes to data to be verified.
It is up to the project to implement the contract so that users can propose changes to the soul off-chain, and it is up to the project to verify that the changes are valid and update the on-chain changes.
1.2.5 Basic SBT Use Cases
The underlying implementation of SBT is suitable for projects that wish to distribute data to non-private users. For example, projects that want to reward whitelisted support for NFT collections can use base SBT. In the future, such projects can airdrop rewards to these SBT addresses.
In a previous article, we presented how SBT can be used as a potential use case for identifying NFT Lockers.
For example, when an NFT is locked in TimeLock.sol, the Locker may still want to “show” that they do have such a locked NFT. However, ref-locked NFTs are strange from a developer’s perspective. Therefore, “soul-bound” tokens can represent how long a user locks up an NFT, and they can be allowed to enter the “hall of fame”. Upon unlocking, a non-transferable wrapper token needs to be “burned” to unlock the NFT, and Locker will no longer have “hall of fame” status.
1.2.6 Privacy Requirements of SBT
However, the basic SBT described above does not take into account the need for privacy.
As mentioned in the previous article, the future of web3 is bound to involve some level of integration with your real identity. Therefore, maintaining the privacy of personal identities after on-chain integration is critical in order to protect themselves from malicious actors who, for example, can view public data on the blockchain and restore personal identities.
Any relationship recorded on-chain is instantly visible to anyone in the world, not just the participants. By correlating SBT data, malicious actors can restore the real identity of the user from the soul.
For example, if Proof of Humanity becomes more widely used, protecting privacy will become even more critical, as the alternative is that everything we do will be directly linked to a human face on-chain.
2. Private storage of SBT data
Buterin proposed some possible privacy-based SBTs in his research article, which can be implemented through on-chain storage and off-chain storage.
In this section, we discuss possible implementations of private storage of SBT data.
2.1 Store data on-chain, but “hash” addresses
- Store the data item in an address that is a hash of the following data: (1) the index, (2) the recipient address, and (3) the recipient-specific secret.
- You can reveal your secrets to an interface and it will search all possible data items that belong to you, but no one will know which specific items are yours unless you leak it yourself.
- The secret provided by the user will allow the platform to find all data related to the user’s SBT.
- This method is also known as Keyed Hash Message Authentication (HMAC). It is a message authentication code obtained by running a cryptographic hash function on the data and shared secret.
- Why does this method work? Ethereum addresses are generated by a Keccak -256 hash and are represented as hexadecimal numbers. The last 20 bytes of the Keccak -256 hash are used to generate the address.
- Because a hexadecimal number is 4 bits, we take the last 40 bits of the Keccak 256 hash as our address. We can deploy our project at this address.
- However, note that hashing with private data should be performed off-chain, since everything on the blockchain (including private state variables) is public.
- Therefore, when deploying or minting, you should only provide hashes, not private data.
(The picture above shows how to deploy user privacy data on a specific address)
For example, Bob wants to mint an SBT using a credit-based lending dApp.
- The lending platform first performs KYC verification on Bob.
- The deployment address is generated from Bob’s client ID, his on-chain address, and his secret (privacy content) named “Peanut”.
- Bob’s customer ID, address, and secret are hashed together to obtain an address for the data deployment address.
- Then deploy an SBT containing Bob’s KYC data on the deployment address chain.
- No one can view Bob’s KYC data except someone who knows Bob’s secret.
- When a project wants to see Bob’s KYC data, all Bob needs to do is provide his secret “Peanut” so they can get all of Bob’s KYC data.
2.1.2 Discussion on hashing on SBT chain
This approach allows for easy interoperability with the protocol, as all we need are the secrets, indexes, and addresses needed to retrieve the data item.
However, deploying data items to specific addresses is cumbersome and consumes a lot of gas.
Also, it doesn’t make sense to store all SBT-related data on-chain, and some data may be more suitable to be stored off-chain.
More importantly, the user’s secret is in the hands of the project party; long-term use may lead to leaks, similar to password leaks that are common today.
2.2 Use third-party providers such as IPFS to store data items off-chain
As mentioned in the previous section, it is too costly to store most data on-chain. Therefore, a better approach is to store the data off-chain on a third-party platform such as IPFS or other cloud services. This method of storing data off-chain is very similar to NFTs, whose data is usually stored off-chain as well.
The difference is that to ensure privacy, we first have to hash the URI string using a cryptographic hash function such as SHA256. Hashing of URI data should be done off-chain because all data on the blockchain is public, even private state variables.
To prevent brute force attacks from identifying links that contain off-chain data, the hash should not be just the hash of the link itself. It can be a function of user secrets, linked to an off-chain data store, or use recursive hashing or other methods. This is also known as salting.
Here is an example Python implementation using SHA256:
This is just an implementation example. There are many other ways to obfuscate URIs, such as randomly appending secrets, generating random secrets, peppering, and using other algorithms specifically designed to store passwords securely.
The on-chain deployment of SBT is then performed using the hash of the data, rather than the data itself.
2.2.1 Connect off-chain data to on-chain hash link
How can we connect off-chain data with on-chain hash links?
One possible approach for contract owners is to standardize data structures stored in off-chain locations. So the owner of the SBT can reveal the link to the off-chain data, and the project (not necessarily the same as the deployer) can hash the link to check if it is the same as the on-chain hash. If the hashes are the same, projects can make queries to retrieve data stored in off-chain locations.
To protect user secrets, verification of links containing user data must be done off-chain by a trusted, secure third party.
2.2.2 Off-chain secrecy risk
Transferring secrets off-chain can expose users to vulnerabilities and various attacks.
Projects must secure secret transmissions and prevent common attacks such as replay attacks, man-in-the-middle attacks, and many others.
Once the security of the third party handling the SBT retrieval is compromised, the individual’s secrets are made public.
Projects should also be aware of phishing attacks, as users may be prompted for a password on a malicious website that replicates the original password.
Furthermore, the only way to prove that a user has a certain attribute is to disclose the secret. However, in order to create the anonymous compositionality of SBT so that different protocols can retrieve SBT data, users should expose the necessary minimum amount of data.
If all the project needs is to verify a property, the user should not reveal the full secret. Users should disclose their secrets to as few projects as possible.
Therefore, we need to consider another approach where the project is able to verify that the user has a certain property without the user revealing their secret.
In this article, we present the implementation of SBT based on the design guidelines presented in the first article of this series. We implemented base SBT as well as SBT with on-chain and off-chain private storage. However, off-chain storage may not be truly private, as users will have to disclose their secrets to prove that they possess a certain property.
The use of ZK (Zero Knowledge Proof) technology can help us reduce the amount of secret sharing of users to keep their SBT data truly private. This leads to the third article in this series, in which we will introduce an SBT implementation using zk-SNARKs, in which the user’s secrets can be kept hidden from various means s attack.
Posted by:CoinYuppie，Reprinted with attribution to:https://coinyuppie.com/spartan-labs-research-report-basic-sbt-and-implementation-of-privacy-sbt/
Coinyuppie is an open information publishing platform, all information provided is not related to the views and positions of coinyuppie, and does not constitute any investment and financial advice. Users are expected to carefully screen and prevent risks.