Skip to main content

One post tagged with "v2"

View All Tags

ยท 4 min read

Today we released Sourcify v2 ๐ŸŽ‰

The changes do not affect the Sourcify Server API in a non-backwards compatible way. If you are using the Sourcify API you don't need to worry. However are some non-breaking additions detailed below.

Why is this a major update then?


The motivation for these changes is to make Sourcify verification more reusable. The lib-sourcify package can be imported into other projects and verify a contract given the source files, and chain&address. Another goal was to create modularity in the codebase with more separated concerns. With these changes, Sourcify server consumes the core lib-sourcify functionality, and takes care of the rest: providing an API, validating inputs, and storing the results (in the repo) etc.

This is in line with what we want to achieve with edge verification. We beleive a contract verification should be easily reproducable and you should be able to verify contracts locally without relying on a third party.

Imagine you're interacting with a contract on your wallet. Before you sign a transaction your wallet:

  • fetches the contract's source code from IPFS
  • compiles and verifies with lib-sourcify

without even talking to Sourcify or any other verifier, everything happens on your local machine. Similarly a block explorer like Otterscan can give its users the option to either fetch the verified source code directly from a verifier (like Sourcify), or verify the contract locally on the frontend.

However, the library as is it not compatible with browsers yet and we are working on it. If you are knowledgable on this front and want to help us, please reach us out.


The brand new @ethereum-sourcify/lib-sourcify is the library that will do all the weightlifting of assembling a contract (e.g. source files) into a compilable CheckedContract, compiling, and verifying it. You can pass checkFiles your contract source code and metadata.json to pack compilable CheckedContracts.

const pathBuffers: PathBuffer[] = [];
path: filePath,
buffer: fs.readFileSync(filePath),
const checkedContracts: CheckedContract[] = await checkFiles(pathBuffers);

Then you can verify this CheckedContract against a contract that is deployed on a chain at an address.

const goerliChain =   {
name: "Goerli",
rpc: [
chainId: 5,

const match = await verifyDeployed(

console.log(match.status) // 'perfect'

Context Variables

In previous versions we introduced "verification with simulation", that is, executing the contract's compiled creation bytecode on an EVM to see if it will yield the same onchain deployed bytecode at the given chainId & address. This allows us to verify "contracts with immutables created by factory contracts".

With this we let the user pass contextVariables to the "simulation". These variables are useful when they are used as a value to an immutable variable in the contract's constructor. Currently you can pass two types of variables:

const contextVariables = {
msgSender: '0x00878Ac0D6B8d981ae72BA7cDC967eA0Fae69df4',
abiEncodedConstructorArguments: "0x0000000000000000000000000000000000000000000000000000000000038efe",

const match = await verifyDeployed(

(In the server API, find the field contextVariables)

For example, if you have a contract like this:

contract Child2{
address immutable public owner;
owner = msg.sender;

passing the msgSender variable allows lib-sourcify to assign this variable inside the bytecode, and be able to verify, because it's an immutable variable. If there are other potential variables that are used as a value to immutables in contracts, please let us know.

Creator Tx Hash

We can also verify contracts by looking at the tx.input of the transaction that created the contract. If this matches the creation bytecode of the compiled contract AND the address resulting from the tx.from and tx.nonce matches the given address, we can verify the contract.

const match = await verifyDeployed(
"0xe75fb554e433e03763a1560646ee22dcb74e5274b34c5ad644e7c0f619a7e1d0" //tx hash

(In the server API, find the field creatorTxHash)


You can also verify CREATE2 created contracts:

const match = await verifyCreate2(

console.log(match.chainId); // '0'. create2 matches return 0 as chainId
console.log(match.status); // 'perfect'

Questions? Feedback?

As usualy feel free to reach us out on Twitter, Matrix chat, or Gitter.

โœ… Happy verifying!