npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@ethereum-sourcify/lib-sourcify

v1.9.3

Published

Library for Sourcify's contract verification methods, contract validation, types, and interfaces.

Downloads

163

Readme

lib-sourcify

codecov

lib-sourcify is Sourcify's reusable backbone library for verifying contracts. Additionally it contains:

  • contract validation methods for creating CheckedContracts
    • an abstraction for a contract ready to be compiled and verified: fetching and assembling its source files, compiling etc.
  • Sourcify types and interfaces

Solc Compiler

The lib-sourcify library does not come with the Solidity compiler as a dependency. Instead, you need to provide a class that implements the ISolidityCompiler interface and pass it to any function that requires a compiler.

// The external Solidity Compiler
import solidityCompiler from "./compiler/solidityCompiler";

// Include also CompilerOutput and JsonInput as dependncies of ISolidityCompiler
import {
  ISolidityCompiler
  CompilerOutput,
  JsonInput,
} from "@ethereum-sourcify/lib-sourcify";

// The custom class implementing ISolidityCompiler
class Solc implements ISolidityCompiler {
  async compile(
    version: string,
    solcJsonInput: JsonInput,
    forceEmscripten: boolean = false
  ): Promise<CompilerOutput> {
    return await solidityCompiler.compile(version, solcJsonInput, forceEmscripten);
  }
}
const solc = new Solc()

// Pass the class to the functions that needs it
const checkedContract = new CheckedContract(
  solc,
  {/** metadata */},
  {/** solidity files */},
)

Validation

The initial step to verify a contract is to validation, i.e. creating a CheckedContract. This can be done with checkFiles which takes files in PathBuffer as input and outputs a CheckedContract array:

const pathBuffers: PathBuffer[] = [];
pathBuffers.push({
  path: filePath,
  buffer: fs.readFileSync(filePath),
});

For a CheckedContract to be valid i.e. compilable, you need to provide a contract metadata JSON file identifying the contract and the source files of the contract listed under the sources field of the metadata.

const checkedContracts: CheckedContract[] = await checkFiles(solc, pathBuffers);

Each contract source either has a content field containing the Solidity code as a string, or urls to fetch the sources from (Github, IPFS, Swarm etc.). If the contract sources are available, you can fetch them with.

CheckedContract.fetchMissing(checkedContracts[0]); // static method

By default, IPFS resources will be fetched via https://ipfs.io/ipfs. You can specify a custom IPFS gateway using process.env.IPFS_GATEWAY=https://custom-gateway, if you need to pass additional headers to the request (e.g. for authentication) you can use process.env.IPFS_GATEWAY_HEADERS={ 'custom-header': 'value' }.

You can check if a contract is ready to be compiled with:

CheckedContract.isValid(checkedContracts[0]); // true

Verification

A contract verification essentially requires a CheckedContract and an on-chain contract to compare against the CheckedContract.

Deployed Contract

You can verify a deployed contract with:

export async function verifyDeployed(
  checkedContract: CheckedContract,
  sourcifyChain: SourcifyChain,
  address: string,
  creatorTxHash?: string,
): Promise<Match>;

a SourcifyChain here is the chain object of ethereum-lists/chains. This states which chain to look the contract in (e.g. chainId) and through which rpcs to retrieve the deployed contract from.

const goerliChain =   {
  name: "Goerli",
  rpc: [
    "https://locahlhost:8545/"
    "https://goerli.infura.io/v3/${INFURA_API_KEY}",
  ],
  chainId: 5,
},

const match = verifyDeployed(
  checkedContract[0],
  goerliChain,
  '0x00878Ac0D6B8d981ae72BA7cDC967eA0Fae69df4'
)

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

Create2 Contract

Alternatively you can verify counterfactual contracts created with the CREATE2 opcode. This does not require a SourcifyChain and address as the contract address is pre-deterministicly calculated and the contract is not necessarily deployed.

export async function verifyCreate2(
  checkedContract: CheckedContract,
  deployerAddress: string,
  salt: string,
  create2Address: string,
  abiEncodedConstructorArguments?: string,
): Promise<Match>;

Example:

const match = await verifyCreate2(
  checkedContract[0],
  deployerAddress,
  salt,
  create2Address,
  abiEncodedConstructorArguments,
);

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

Logging

lib-sourcify has a basic logging system

You can specify the log level using the setLibSourcifyLoggerLevel(level) where:

  • 0 is nothing
  • 1 is errors
  • 2 is warnings [default]
  • 3 is infos
  • 4 is debug

You can override the logger by calling setLogger(logger: ILibSourcifyLogger). This is an example:

const winston = require('winston');
const logger = winston.createLogger({
  // ...
});

setLibSourcifyLogger({
  logLevel: 4,
  setLevel(level: number) {
    this.logLevel = level;
  },
  log(level, msg) {
    if (level <= this.logLevel) {
      switch (level) {
        case 1:
          logger.error(msg);
          break;
        case 2:
          logger.warn(msg);
          break;
        case 3:
          logger.info(msg);
          break;
        case 4:
          logger.debug(msg);
          break;
      }
    }
  },
});