 I'm working on the Ethereum Foundation on the project Sourcify and today I will be talking about how we can enable more human-friendly contract interactions using Sourcify verification. I'll start with showing you guys something you're all familiar with. I would say if you're a WebTree user for a while, just a normal day in WebTree and I guess this will be like something you see every day. Every day in WebTree you'll see things like this and you basically have no idea. You're not a machine. You don't understand what's going on. You're trying to make sense of it. Am I doing the right thing? Am I talking to the right contract? Is this doing actually what I want to do? And basically what you do is telling them to shut up and take your money. You have no idea what's going on, you're just giving out your money. And we say today a typical WebTree interaction is still a YOLO signing nightmare, what we call YOLO signing. It's just they give you things to sign and you just sign them, hope for the best. So at the end of the day what we want to have is more to do something on the right hand side, from left hand side to right hand side. So I know this has changed actually for many wallets. So many wallets actually started to decode things like MetaMask using Truffle and decoding the ABI. But still we have a long way to go and we have a lot of things that we can improve the user experience. So what can you do to achieve this? There are two sides of this coin. So there are things you can do as the world developer and there are things you can do as the smart contract developer. So let's dive in what you can do as the smart contract developer. The first thing you can do is using a Nutspec documentation and as well as doing the source code verification on Sourceify. So what is Nutspec documentation? Nutspec documentation is what is called Ethereum natural language specification format. It's actually part of the Solidity spec. And probably you have seen this if you have seen a contract before. This is how it looks like. You put the comment, the documentation above the function and you have the developer documentation, you have the user documentation with the at notice field and you have the documentation for the parameters. So another nice thing about Nutspec is it has the specification for dynamic expression. So the field you see here, the old owner and new owner parameters in back quotes, these actually can be filled dynamically with the value they are being called. So this replaces the owner, the address can get filled and the new owner can also get filled in the parameters. So you did your job, you made the user documentation, developer documentation. So where do you find it then? Where can I find it? It is in the Solidity contract metadata. So who actually knows what Solidity contract metadata is? Anyone? Just a few people? Cool. That's why I'm here. So contract metadata is actually something introduced early on in 2016 in the earlier versions, but it was actually not really picked up by the community. It is actually a JSON file generated by the compiler itself, and it contains the metadata. Okay, but where is the metadata? It has the ABI, the user doc, Dev doc, as well as compilation info and source file info. So the first two fields actually is concerned with how to interact with the contract. So how to interface with the contract. And then the second two is about how to reproduce a contract compilation. So it embeds the information during the contract compilation so that it can be reproduced. The file looks like this. It's a JSON file. It has a compiler language, settings, source file information. And here, for example, in the output, you can see the user doc and Dev doc. And if we open those fields again, you have the methods. And with the methods for each method, you have the notice field or the Dev doc field if there's a Dev doc. And you have the, for example, in this case, the replaces the new owner with the old owner with new owner. The comment we have seen before. You can get the metadata with the metadata flag on the compiler itself. On with the frameworks, you can find it inside the build files. So truffle, for example, puts this inside the build contracts, the contract name JSON. Under that, you can find the metadata fields and the metadata is there. That also started to output metadata for inside the build file again. You can find the metadata here. Yeah. You can also find the traces of the metadata inside the bytecode. So the bytecode, this is an example contract bytecode. And the bytecode has actually a special field at the end of the bytecode. It is appended by the compiler. Again, a question, who knows what this is? Okay, again, just a few people. And again, that's why I'm here. So this field, the compiler actually takes the IPFS hash of the metadata file, the file we saw, and it encodes the IPFS hash of that file here alongside some other information. Maybe I'll pull this as well. Alongside some other information. And yeah, you can see how this works in our playground, Playground Source 5.dev. We basically show how the encoding is done, what the encoding contains, and we also try to find metadata from IPFS. It's already there. So it's a nice tool. There are some example contracts you can click on, or you can just provide us with the contract address or just paste the contract bytecode. And we will try to visualize how this thing works. All right, let's go down to the second thing, source code verification on source 5. But before, what is source code verification? So this is, for all of you know, you probably have seen this if you have seen a contract before. And you see a green check mark. You're happy. You know the contract, right? OK, but how does this work? Maybe before that, the reason we need, why we need source code verification is that the contracts actually live on blockchain as bytecodes. They are, we humans write code in human language, but the machines read it in bytes. So the code gets compiled and deployed to the blockchain, and this information is lost in the process. So we need to somehow make sure just a random code you see is actually the code behind the contract. So that's the process of knowing this code is actually the one that is running the contract is source code verification. So how does this work? You have the contracts, Solidity files, in this case. You have a target contract. You also have compilation settings like the version, the optimizer settings, the other things. And we feed those into a compiler, and we recompile the contract. And remember, this is actually when the second part of the metadata information comes in handy. So we use this compilation info to reproduce the compilation of the contract again. So we feed this into the compiler, and the compiler gives us a bytecode. And we also have the contract that we want to verify. So we get the code of the contract from the blockchain. This will give us a bytecode. Then we'll see if these actually match. And in sourceify, we also have two types of matches. We have the partial match, when bytecode match, and we have the full match when both the bytecode and the metadata field match. So right now, today, when you are verifying on Etherscan or any other verifier, they actually ignore this field. Like they don't make use of this field. They just trim it out. And actually, there have been cases that this was exploited. So it wasn't a serious thing, but this wasn't really doing what's being done properly. But yeah, with the full match, you have a complete match of the bytecode. And here, the metadata actually acts as a compilation fingerprint. So if you match the metadata as well, the compilation is exactly the same as the original, as when the contract was deployed. And the full matches actually cryptographically guarantee that the whole compilation is exactly the same, including the solidity files, comments, spaces, variable names, anything. Like even if you change a space, a variable name, it will break the match. So how does this work? Let's see how this actually works. Again, when you are compiling your contract, the compiler takes the hash of each file, each solidity file, then the hashes of these files are actually embedded inside the metadata file, or the metadata file that we saw, as well as the other sources, not just one. Then, as said, the compiler takes the IPFS hash of this whole file, and then this IPFS hash is embedded at the end of the bytecode. And then we see if these match. If it's a full match, it's a match. It's a full match, if they match. And let's see what happens when you change something. When you make a slight change, change the space, change the variable name, any comments. So we have my contract div this time. So the hash of the file will change. Then the hash inside the metadata will change. And in turn, the hash of the metadata file itself will change. So this field will be different this time. And that means this will not be a full match, but this will be a partial match. Assuming you didn't make a change, that will change the functionality of the contract, just a comments or variable. OK, but then how to verify? So you can use the source.fi UI. You can give us the source code and the metadata file. We need the metadata file. We're able to verify, either from your computer, or etherscan, remote, GitHub, however you like. Then you give us the contract address, contract chain. We try to verify. You can use the API. We have an API endpoint, and other several API endpoints as well. You can check them out in docs.source.fi.dev. We have some detailed docs about this. And we also have the tooling. So if you are using hardtatt, there's a hardtatt deploy plugin. And with the plugin, after you deploy your contract, you can just pass the network back and then say source.fi and easily verify your contract. We have the remix plugin. If you are using remix, you can provide the contract address, the chain, then we will verify. We recently have Foundry support. So using Foundry, you can also easily verify your contracts. And we also have some automatic verification, so what we call monitor. So we have a monitor running that is listening on several chains. We are right now listening to, if you remain net test nets, as well as some rollups, as far as I remember. So the monitor, what it does, it catches contract creations. And then when it finds a contract creation, it will fetch the metadata. As you remember, it's like IPFS hash is over there. So it will get the IPFS hash, try to fetch it from IPFS. And also the metadata file has the source hashes, it will try to get the source files from IPFS as well. If it finds them, then it will automatically compile and try to verify the contract. So that means actually the second step here, the source code verification on source.fi has become publishing your metadata. So you don't even have to take the extra step and go to source.fi and verify your contract. If you just publish it and pin it on IPFS, we'll just do it for you. Yeah. So we have this contract repo of all verified contracts. It is served over HTTP and IPFS under repo.source.fi dev. So we pin the verified contract source files and the metadata so that they will be accessible by decoding the bytecode. So here, remember, there is the IPFS hash here. And anyone, if it's verified on source.fi, we will be pinning it. And there are other people pinning our repo as well. So they will be accessible by their IPFS hash. And yeah, we also served repo under an IPNS name, but repo.source.fi dev. So you can also see the contract repo and see the files, access all of them, download the whole repo if you want. So yeah. Okay, so we have seen what you can do as a smart contract dev. Let's see what you can do as a wallet developer. So maybe a short recap, what we are trying to do again. So we have a contract call. We are talking to a contract. And instead of showing, instead of this byte string, we want to show something more user-friendly. So one thing to do is obviously to decode this call, this byte string call via the ABI JSON. You can show the function name, the variable names, et cetera. And then you want to show some human readable description of what the user is trying to do if you have documented your code well. So what you can do as a wallet developer, you go to source.fi, you repo.source.fi dev, you get the chain ID, the contract, and the metadata. No, please don't do that. You don't come to us because it's already on IPFS. And the neat thing is it is content address. So you know the file you are getting is actually the right file. So your wallet just gets the byte code of the contract, decodes the IPFS hash here at the end of the byte code, fetch the metadata that we pinned it for you, and the metadata file as we have seen, the ABI and the documentation. Yeah, this is where the first two fields come in handy, how to interface with the contract, and then decode the ABI and populate the nutspec comments of the contract. So hopefully at the end of the day, we will have something more on the right rather than something on the left. But source.fi is actually not the only way for human friendliness. The idea behind source.fi is to have human readable descriptions via nutspec, comments found in the metadata. There are other ways to achieve this as well. For example, these two EIPs by Richard Moore and Nick Johnson. So the idea there is to have an extra function name, an extra function, a describe function, so to say, that will return the user something unreadable. So it can be anything, any custom string. And the contract will return the string to the user and continue executing the actual function. And here the nice thing is it can decode things like ENS commit that is normally like it's a hash commit and it doesn't have a meaning to the user. But you can add actually some more custom strings, custom messages to the user that they can make sense of it. But obviously this costs extra gas. The other one is the IP proposal by Dan Finley. There the idea is to give the user this information at the first point of contact. So say you want to do an exchange for the first time at Uniswap, Uniswap app, app.uniswap will give you the contract metadata. Your wallet will store it. And then your wallet will have the ABI and the describers so that it can show you something more human readable. The advantage here is it's backwards compatible. So we don't need to change the contracts. Right now most of the contracts don't have any documentation or anything and or they are not actually documented with the human friendliness in mind. So this will be backwards compatible but at the same time this means it's mutable. So it's like it can be changed. So it's a trade-off. And also there are many ways to better UX. So we can actually show the users many things. So is it you can decode the contract, call, you can warn if the user has never been talked to this contract, show the user if the contract is verified, block if it's a scam address, many things as well as other types of things such as how many times this contract was interacted with, when was it deployed, because a scam contract would be likely more recent and less interacted with. Is this contract audited and is it audited by whom? So there are actually many ways we can do better. So as a recap, what is Sortify? Technically it is an open-source automatic smart contract verification service, our monitor. It's a user interface, server, API, and tooling to verify contracts manually. It's a publicly centralized content address storage of verified contracts, our repo. And more generally, we are a base layer and a public good for other tools to build on top of us. And we are an initiative to foster the use of Solidity metadata, nut spec, and full verification. And as well as we are an ongoing effort to improve smart contracts' safety and transparency. So thank you for listening. If you're interested, you can find us in Twitter, join our matrix chats. Our code is also at here, ethereum.srcify. Visit our website. And I'll be happy to take any other questions if you have. Thank you. I'm wondering how well these solutions can handle translation and internationalizations to provide descriptions in multiple languages. Yeah. That's also one consideration. There, we have the idea of maybe having a custom nut spec field for translations. And in that field, you can actually link to another translations file. So that would be inside the metadata, for example, the translations file. And that will be another IPFS hash. So that you can fetch it and you can have other languages and translations. Are you thinking about UX regression testing automation somehow? Sorry? Are you thinking about end-to-end regression testing automation with Solidity? So being able to include the dApps in the whole cycle of testing how things look like. Like what can dApps do to make things easier for end users to understand? So having the certify at the whole development pipeline, you mean? Or I'm not sure if I get the question right. Correct. Currently, in order for a developer to somehow test the end-to-end user experience, it's nearly impossible to include the web app and the wallet interaction and the on-chain interactions. I'm not sure if I get the question correctly. But you are more like a, we just say people, here are the tools, here are the files. Just please make use of it. So we don't actively get involved in the UX contract interactions, or that's not in the whole complete pipeline, I would say. For user protection, am I right in thinking that the reputational and statistical characteristics you mentioned are really important? I'm sorry, I was talking. Right here. Because I'm just thinking, and correct me if I'm wrong, but a malicious deployer could create a malicious contract, describe it in a malicious way with NAT spec, and then take advantage of the user. Yeah, I mean, obviously, we have the assumption that the contract deployer is mine. It's not malicious. So we verify the content of the contract. But as I said, there are other ways to do that, for example, audits, scam lists. So this is another aspect. So we have this neutral eye towards inside the contract, and it's up to the community and the other types of methods to actually see it's not a malicious contract. Thanks for the talk. So question I had was for contract coverage. Like, is it limited to what's verified on etherscan, or in terms of like, ABIs that might not be fully complete? Like, what does sourceify fully cover? What do you mean by cover? In terms of contract coverage, if someone deploys a new contract, it's not verified on etherscan, then do you guys still provide the human-readable aspect? Yes. I mean, sourceify is a completely different thing than etherscan. Etherscan is both a verification service and a block explorer. But sourceify is not a block explorer. We are just a contract verification service. And I would say we have different contract sets than etherscan. So you can actually import, but it's a different contract set. So even for new contracts, you guys instantly get into the pipeline, verify, and then make it readable. Yeah, exactly. Any contract that is deployed, we can just verify. Gotcha. And even also different chains. Like, we have, I think, like 30-something EVM chains right now. So you can even verify contracts on other chains. But at the end of the day, actually, we have support for different chains, but we actually want everyone at some point to run their own sourceify for their own chains. Cool. OK, thank you. Maybe the last question. Is it in the scope of sourceify to maintain reputation of the commands, or maybe even validate the commands, actually reflect the code? What documents, or does it sound here is not so good? Is it in the scope of sourceify to maintain a reputation score for the commands, or to validate if the commands reflect the code? The application commands, you say? Yeah, the commands. Commands. I mean, no, we just, as I said, we are a tool to achieve this. And at the end of the day, the developers have to document and comment their code. So they have to keep in mind that this might be a user-facing method and properly documented. Thanks. I think we're out of time. Just find me after the talk, or also you can find sourceify and reach us out there. Thank you.