New Ethereum talks, every Monday. The week's conference uploads by event, in your inbox.

Loading player…

Self Protocol Workshop I Ayman Mohammed

ETHGlobalSun, Nov 9, 2025, 12:00 AM

Ayman Mohammed’s workshop introduces Self Protocol, a decentralized identity solution that eliminates the need for traditional KYC by enabling users to verify personal attributes without exposing sensitive data. Instead of sending full identity documents to third parties, users register once using passports, Aadhaar, or biometric IDs, generating a unique nullifier to ensure civil resistance and privacy. The system uses zero-knowledge proofs (ZKPs)—specifically Groth16 and Circom—to verify attributes like age, nationality, or OFAC compliance, allowing users to disclose only what’s necessary. Self’s registration process anchors identities in an onchain Merkle tree, ensuring anonymity and preventing duplicate sign-ups while maintaining verifiability. During the session, Ayman demonstrates Self’s SDK and QR code verification flow, where users scan a QR to selectively prove claims (e.g., “over 18” or “not from the U.S.”) via the Self mobile app. Developers can integrate this using the onchain SDK, writing custom smart contracts that inherit from SelfVerificationRoot and define hooks for proof verification. Ayman emphasizes onchain verification as the most trustless option, avoiding backend censorship risks. The session concludes with new SDK features like programmatic config creation, scope handling improvements, and simplified contract deployment. Self’s hackathon bounties prioritize onchain integrations with higher rewards to encourage developers to build privacy-preserving verification systems for decentralized apps. 00:02 – Introduction to Self Protocol and session overview 00:29 – Problems with current KYC systems and data security risks 00:54 – Why Self eliminates unnecessary KYC through selective disclosure 01:19 – How Self uses passports as trusted, machine-readable identifiers 02:08 – Nullifiers and civil resistance via identity-based proofs 02:43 – Selective disclosure of personal attributes for privacy 03:03 – Custom claims: age verification and OFAC exclusion checks 03:56 – Aadhaar and biometric ID support for broader global coverage 04:26 – Two-step process: registration and disclosure explained 05:10 – How registration ensures anonymity and prevents duplicate identities 05:41 – Role of trusted execution environments (TEEs) in proof generation 06:14 – Overview of ZK proof stack (Groth16 + Circom) 06:42 – Developer integration using QR codes and SDKs 07:04 – Onchain vs. offchain verification and trust assumptions 07:35 – Hackathon bounties and prize structure for Self integrations 08:14 – Live demo setup: QR-based disclosure of age and country attributes 09:23 – Using the Self app to scan and verify attributes in real time 09:56 – Explanation of Self app builder config and parameters 10:31 – Verification process walkthrough with test network 11:09 – Smart contract example: extending SelfVerificationRoot 11:53 – How to override hooks for proof verification and event logging 12:36 – Matching frontend and contract verification configs 12:56 – Contract deployment setup and configuration example 13:26 – Repository overview: frontend QR code + Solidity contracts 13:55 – Handling multiple ID formats and disclosure data differences 14:21 – Specification nuances: passport vs. Aadhaar data formats 15:13 – New SDK improvements: programmatic config setup and scope handling 16:01 – How the latest update simplifies verification configuration 16:20 – Final notes, Q&A, and booth invitation _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 🇮🇳 *ETHGlobal New Delhi* This workshop is specifically for ETHGlobal New Delhi, a 3-day hackathon held September 19-21 at the India International Convention & Expo Centre, bringing together the most skilled web3 developers, designers and product builders from all around the globe for a weekend-long adventure to advance the Ethereum ecosystem! Watch the full ETHGlobal New Delhi 2025 playlist here: https://www.youtube.com/playlist?list=PLXzKMXK2aHh7zCFW3hBqatZ18rQaYeEJL _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ✅ *Follow Self* X: https://x.com/SelfProtocol ✅ *Follow ETHGlobal* X: https://x.com/ETHGlobal​ Warpcast: https://warpcast.com/ethglobal Website: https://ethglobal.com YouTube: https://www.youtube.com/c/ETHGlobal _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _Are you interested in Ethereum development and entrepreneurship?_ 👉 Sign up for the next ETHGlobal event: https://ethglobal.com/events 🎁 Get exclusive access and perks with ETHGlobal Plus! https://ethglobal.com/plus 📣 Want us to throw an event in your city? Tell us where! https://ethglobal.com/city

Transcript

[Music] Today I'll I'll give you a workshop of how self protocol works and some new feature we've launched that you might have heard about already. But yeah, this is an overview of what um today's workshop is. So I'll talk a bit about self, why we need self in the first place, the boundaries and the code example like probably a live demo. Yeah. So what what what's before we talk about self what's the issue with existing KYC solutions?

What they do is um they they take your data and then they they store it insecurely. Like if you heard of the T hack um they had a public AWS um Firebase bucket. So um all your data was like stored there and then um it got it got leaked because it was public and yeah it was pretty bad. So it it it's also like pretty bad user experience because someone has to manually verify your um data. It's going to take days and then it's it's very privacy in invasive and it's making you uncomfortable in general to um login with um any any any um third party app.

So I so self is not um a KYC provider. What we plan to do is eliminate KYC where it's not needed. So why would you um just to verify that you're above 18 send your entire Aadhaar data to some um website and so they can store insecurely and then later get hacked. So yeah that's where self comes in where you can have um where you can um reveal data about yourself without really revealing anything. So what how we do is so yeah why why how so when we released we started off with passports and why would so why would we use passports?

So one thing is they are difficult to obtain and they are unique per per um the issuing country. So there's there's a trust assumption on the government but um if if you don't trust the government then there's like bigger issues but yeah so and there's and there's also machine readable so it's easier to work with like if you see the bottom part of your passport it has a machine readable zone and what you can do is it's pretty easy to work on top of that and integrate that into automate that existing system and you you would also get like one nullifier. So nullifier is a unique identity for unique um hash I would say for your identity and it it provides a good um way to tackle civil resistance. So I so previously what people did was um they to do civil resistance you had to bring in some capital and like you had to stake some amount or you had to do some proof of work but like you can also use it using identity and have some build it on top of an existing trust solution that that is um identity solution that's like from the government and not only that um not only do you tackle civil resistance you can also disclose certain facts about yourself so in a privacy preserving way you can choose to only reveal your name in a verifiable way and only that gets revealed and nothing else. So a name is not that useful.

So there's other attributes such as date of birth, issuing state, nationality, gender and so on. And not not only that, we also have some custom claims that you can integrate into your SDK such as you have to be above a certain age or you're not from a set of countries which um if you're using the existing SDK, it's like a max of 40 countries you can set and you're not on the OFAC list. So the OFAC list is a US sanctioned list that has a list of all the criminals. And what you can do is if you if you need some some compliance in your app in your app then what you can do is you can just um add this check and see if a person is not like a criminal inside this list and yeah so not only passports we also support Aadhaar now so it's so before passports had like 1.1 billion um users but Aadhaar is like 1.

4 4 billion and you can target almost every Indian who has an Aadhaar which is like almost everyone and there's also biometric ids that we support. So these are a bit of different thing and it's mostly issued in like European countries and some other countries like Ghana and Argentina but it's it's still um a verifiable solution for identity and how how does it look like? So we have two steps inside the self protocol. So the first thing is registration. So what you do with registration is register yourself in an onchain Merkel tree.

And what this does is you know make sure that you don't register twice and so on. And so it's kind of similar to tornado cache or like semaphore from PSC if you've heard of either protocols. Um the the thing is first you register into some anony anonymity set inside on in an onchain contract and then you you prove you're part of that onchain set when you do a disclosure. So disclosure is basically um one thing is proving that you're legitimate person like you got registered inside this onchain merry and the next thing is you reveal some attributes about yourself and um you can do it. So the first registration step verifies your entire document data and when you disclose you don't have to verify it again because it's already registered on chain and um it's like much more efficient and this is different from other passport protocols that would do the registration and disclose step in a single step.

So that's kind of dangerous because you can link your revealed attributes to your nullifier which is which is trackable trackable by the government and so on and yeah how how does um the registration flow work? So you have this passport or your ATAR data that's stored inside your mobile app and you also have a secret that is based on your biometric data like your pass key and we store this inside the cloud backup and what we do is we generate we send this encrypted data to a TE that would um generate the proof and submit um submit a proof on why are we using TE because some of our circuits are like the Z keys are 5GB big and they take like even 3 minutes just to approve like a brain pool 512 circuit just um just like a single circuit. So it's it's pretty hard to do client side and we're using circum and groth 16 inside this process which is like the only zk um stack that has been audited extensively and the disclosure is simply um this is what you would um integrate in your app mainly. So this so the registration step step is done by the self app but the disclosure is something you as an integrator needs to work with. So you have a QR code or like a deep link if you're using a mobile app.

But if you're building a web app, it's a QR code and what the user experience would look like is um you show you create a QR code with certain attributes you want to reveal, certain claims you want to check and the mobile app you can scan this um QR code with your mobile app and then create a proof and submit it on chain. So you can either submit it onchain. This is where the onchain SDK part comes in where you write a contract that verifies your proofs and works on top of that data or you can do it inside a backend verifier that would um verify the proof inside a NodeJS server. But um yeah, in general for ZK proofs, you would want to verify it on chain because there's there's a tr there's a trust assumption on the verifier if you do it in in the back end like the verifier can censor some proofs and not accept some proofs. So you would want to do it onchain where um there's some consensus on what what happens.

And moving on to the bounties we have for onchain we have for the first price 5k followed by 2.5k and 1.5k. So these are the prices we have for onchain SDK. So the reason we focus so much on um onchain SDK is like what I said before which is it's it's a more trustless form of verifying your proof like if you do it in the back end you can always choose to not accept a proof and that's not like completely um honest.

So yeah, so that's for onchain and for off-chain we we offer um $1,000 and yeah it's you can see it's like much more for onchain. And moving on to the code examples um I have a demo prepared here so to just just to show you how it works in general. So you can see here this is the cell this is the QR code and this QR code has data about what you would want to um disclose. Let's so if you go inside if I go inside the app um I don't know if you can see it you can see what I'm disclosing inside this disclosures um field. I'm only um proving that I'm not I'm at least like 18 years old and I'm not in excluded countries which is the United States and yeah that's so this is this is like on mock this is like a mock adhar that I'm going to use but the idea is when so um I'm just going to use the self app right now and yeah you can see there's like a Aadhaar document that I have already on me and if I ver I'm just going to scan scan and this QR code which would the app would ask me that I'm going to reveal these properties about myself and then I'm just going to consent that these properties are going to be revealed eventually.

So yeah, it's important that you take a look before you reveal stuff you don't want to reveal. Um, yeah, and this it's going to take a while to lo to load, but meanwhile while that happens, this is I'll go over how it works on chain um for for the QR code SDK at least. So you have this um a self app builder object that has info about your app like your version should be two and the name and the scope and the scope is eventually used to calculate the nullifier and then there's like user ID that you want to associate a given identity to a particular um user. So you can either make it um a Ethereum address or you can use UIDs and here I'm using like a dummy zero address here but yeah I think and the endpoint is like staging cuz I'm verifying it like on on the staging network on like Celosia. So I'm just holding to verify my um document basically.

So it's proving now if you can see it not sure and it verified and it takes you to this page that you're now verified. So, so if you if I um disclose with like a country that has if I disclose with a passport that is from the US and I set that um the country excluded country is like US then it's not going to work because the proof won't be generated because you're from US and you don't want that and that is from so that's the self app builder basically and then you put that inside your QR code which is pretty simple and that's all you have to do on the front end SDK just define a config about your app and then store where you want to verify the proof, what type of user ID it is and some some data that you want to um as um pass in to your contract to do some custom logic that you would require later on. And yeah, that's it for the onchain um QR code. And for the contracts, it's it's it's a simple contract and the main idea is um extending this thing called self-verification route. And there's there's basically two it's a abstract contract.

So there's like two methods you have to override. One is the custom verification hook. So what this does is once your proof is verified what you want to do with it. So we have a relayer system. So we have a relayer because um well if all proofs are sent by the same relayer it's hard to link it to the single person.

So that is one reason why we use a relayer. And um yeah what I'm doing I'm just doing a simple event. I'm just emitting this event once once the proof is verified and I get all this um data. So you can see inside this there's a bunch of stuff that has been revealed and yeah you can work on top of that in your hook and there's also the get config ID. So you notice that in the front end we we had like a certain um certain claims that we wanted to verify.

So this was minimum age and the excluded countries. So this config has to exactly match your offchain or onchain config. These these two should be the same because the claims you're testing should be the same. And it's one way of enforcing that um the same config is used. So you can see I'm setting the config in the constructor here.

You can set it like inside a different function. And when deploying this thing I am yeah I'm saying that it's older than 18 and the forbidden countries should be United States like that's all I would have to set inside inside the contract and yeah so it's just two functions that you have to override and it can be as simple as this and you can have like a bunch of other logic inside your custom verification hook. So that would be offchain and yeah so that is some code example. So so this is the workshop repo if you want you can just clone it and um set the env like deploy the contract and set it inside thev and it's going to work if you want to quickly test out how cells works. So it's so the app directory has the front end and the QR code stuff and the contracts directory has like this proof of human solidity contract that you can um take a look at.

Um yeah so you can also visit our docs and so there's we also support multiple different ID documents. So the format of the disclosed data is not going to be the same. For example, in passports, you only use the first two, like the last two um years. Like basically, if it's 2022, is your it's just going to have 22 inside the passport. And we can't um extract the year.

It could be 1922, it could be 2022. And yeah, so but like in Ahar you have the full year. So if it's 1984, it's going to just stay 1984. And it's it's something to watch out for. And we have documented that inside our docs.

like there's an AAR specification document and yeah so yeah that's all for my talk and you can start us on GitHub and go to our website but do does anyone have questions for me for the self SDK in general or yeah Yeah.

Yeah. So, previously you had to use this tools.xyz thing where you had this um scope you would set the contract address and then um the scope seed and then it would hash it and then you had to set the config ID. So from from like this update, you don't have to do that. So it's going to natively happen.

You can programmatically um set the verification configs like if you saw here um in deploy proof of human. I'm just setting this config. I don't have a config ID thing. I'm just saying it should be older than 18 forbidden countries should be so and so and of enabled. And inside the contract like in the constructor you can see I'm formatting into some more readable format for onchain hub.

And then I'm just setting that inside. You can see the verification config ID is still a thing, but like you can do it programmatically. So you don't have to um set it um again. And you can also see the scope is now a string instead of like a UN 256 um dummy scope that you had to set. So the the um contract like the self-verification root constructor is going to handle all of the scope generation by itself.

So you have to put the contract address in lower case. That's the only thing you have to watch out for. But Yeah, but you don't have to use tools of self.xyzy anymore. Any other questions?

No. Okay, I guess we can wrap it up. You can find me at the booth if you're if Yeah. And we'll be there like Yeah. throughout throughout the whole hackathon.

Thank you. [Music]

Automatic transcript — names and jargon may be misspelled.