Package: inspector-facet
Inspector FacetA tool that allows you to inspect deployedEIP-2535 Diamond proxycontracts from your command line.Inspector Facet was inspired byLouper.dev(GitHub).Inspector Facet uses side information about facet ABIs to match the selectors that a Diamond proxy
is serving to human-understandable information about the facets and the functions.We support side information obtained from:browniebuild artifactshardhatbuild artifactsEtherscan/Polygonscan/etc.Inspector Facet can build a complete audit log of all Diamond-related operations on an EIP2535 proxy
contract. Use this functionality with the--timelineargument.InstallationInspector Facet is written in Python 3 and is distributed using PyPI:https://pypi.org/project/inspector-facet/To install Inspector Facet, run:pipinstallinspector-facetUsageinspector-facet--helpTo use Inspector Facet:With abrownieprojectThe following command produces human-readable output:inspector-facet\--network<brownienetworknameforblockchain>\--address<addressofdiamondcontract>\--project<pathtobrownieproject>\--formathumanThe following command produces JSON output and can be used to inspect a Diamond contract programatically
(e.g. as part of a CI/CD pipeline):inspector-facet\--network<brownienetworknameforblockchain>\--address<addressofdiamondcontract>\--project<pathtobrownieproject>\--formatjsonWith afoundryprojectThe following command produces human-readable output:inspector-facet\--network<brownienetworknameforblockchain>\--address<addressofdiamondcontract>\--project<pathtofoundryproject>\--foundry\--formathumanThe following command produces JSON output and can be used to inspect a Diamond contract programatically
(e.g. as part of a CI/CD pipeline):inspector-facet\--network<brownienetworknameforblockchain>\--address<addressofdiamondcontract>\--project<pathtofoundryproject>\--foundry\--formatjsonNon-standard build directoriesThe--build-dircommand allows you to specify the name of the build directory in yourbrownieorfoundryproject in case you aren't using the standard directories (build/forbrownieandout/forfoundry).To build an audit log of Diamond operations on an EIP2535 proxy contractTo build an audit log, you will need to crawlDiamondCutevents from the blockchain. You can do this usingmoonworm.First, you will need to installmoonworm:pipinstallmoonwormThis should be done in a separate Python environment frominspector-facetbecausebrowniepins its dependencies
and doesn't play nice with other libraries (GitHub issue).Oncemoonwormis installed, you can find the deployment block for your contract:moonwormfind-deployment-w<JSONRPCURLforblockchainnode>-c<contractaddress>-t0.5Save the output of this command asSTART_BLOCK.Then crawl theDiamondCutevent data:moonwormwatch\-iinspector_facet/abis/DiamondCutFacetABI.json\-w<JSONRPCURLforblockchainnode>\-c<contractaddress>\--start$START_BLOCK\--end<currentblocknumber>\--only-events\-o<outputfilename>\--min-blocks-batch1000\--max-blocks-batch1000000If you are crawling data from a POA chain (like Polygon), add--poato the command above.Then, invokeinspector-facetas:inspector-facet\--crawldata<outputfilename>\--project<pathtobrownieproject(shouldcontainbuildartifactsinbuild/contracts)>\--formathuman\--timelineConnecting to a blockchainInternally, Inspector Facet usesbrownieto work with any
Ethereum-based blockchain. When you useinspector-facet, even with ahardhatproject,inspector-facetwill still usebrownieto interact with any blockchain.Anyinspector-facetcommand that calls out to a blockchain will take a-n/--networkargument. The value
of this argument must be the name of abrownienetwork configured in your Python environment.brownieis a dependency ofinspector-facetand is automatically installed when you installinspector-facet.To see a list of availablebrownienetworks, activate the Python environment in which you installedinspector-facetand run:brownienetworkslistThe output will look like this (truncated for brevity):$ brownie networks list

Brownie v1.17.2 - Python development framework for Ethereum

The following networks are declared:

Ethereum
  ├─Mainnet (Infura): mainnet
  ├─Ropsten (Infura): ropsten
  ├─Rinkeby (Infura): rinkeby
  ├─Goerli (Infura): goerli
  └─Kovan (Infura): kovan

Ethereum Classic
  ├─Mainnet: etc
  └─Kotti: kotti

Arbitrum
  └─Mainnet: arbitrum-main
...To view the details for any particular network, use:brownienetworksmodify$NETWORKFor example:$ brownie networks modify mainnet

$ brownie networks modify mainnet
Brownie v1.17.2 - Python development framework for Ethereum

SUCCESS: Network 'Mainnet (Infura)' has been modified
  └─Mainnet (Infura)
    ├─id: mainnet
    ├─chainid: 1
    ├─explorer: https://api.etherscan.io/api
    ├─host: https://mainnet.infura.io/v3/$WEB3_INFURA_PROJECT_ID
    └─multicall2: 0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696If you want to connect to this network, using Infura, all you have to do is set yourWEB3_INFURA_PROJECT_IDenvironment variable (get this information from your project dashboard on Infura) and set--network mainnetwhen you invokeinspector-facet.For networks which have publicly available nodes, it's even more straightforward:$ brownie networks modify etc
Brownie v1.17.2 - Python development framework for Ethereum

SUCCESS: Network 'Mainnet' has been modified
  └─Mainnet
    ├─id: etc
    ├─chainid: 61
    ├─explorer: https://blockscout.com/etc/mainnet/api
    └─host: https://www.ethercluster.com/etcYou don't need any additional environment variables.Adding a custom networkTo add your own network, use thebrownie networks addcommand.The signature for this command is:brownie networks add <label> <network-name> chainid=<chain ID for network> host=<JSON RPC endpoint> explorer=<API URL for blockchain explorer>The<label>is purely for organizational purposes and can be set to whatever string you want.For example, if you wanted to add the public Polygon RPC service as a network, you would do:brownienetworksaddPolygonmaticchainid=137host=https://polygon-rpc.comexplorer=https://api.polygonscan.com/apiSupportYou can get help in any of the following ways:File an issueAsk for help onMoonstream Discord