UNPKG

hardhat-deployed-records

Version:
122 lines (105 loc) 3.65 kB
import { HardhatRuntimeEnvironment } from "hardhat/types"; export async function parseArtifacts( hre: HardhatRuntimeEnvironment, ignoreContracts: string[], ): Promise<{ contracts: { name: string; path: string[] }[]; }> { const fullNames = await hre.artifacts.getAllFullyQualifiedNames(); console.log(fullNames); // examples: // [ // '@openzeppelin/contracts/access/Ownable.sol:Ownable', // '@openzeppelin/contracts/utils/math/SignedMath.sol:SignedMath', // 'contracts/IBar.sol:IBar', // 'contracts/MMERC20.sol:MMERC20', // 'contracts/MMERC20.sol:Bar', // 'contracts/mock/foo/Foo.sol:Foo', // 'contracts/mock/foo/Foo.sol:Foo2' // ] let contracts: { name: string; path: string[] }[] = []; for (const fullName of fullNames) { // skip third-party dependencies if (!fullName.startsWith("contracts/")) continue; // get sourceName and contractName let { sourceName: source, contractName: name, bytecode, abi, } = await hre.artifacts.readArtifact(fullName); console.log("~~~~", source, name); // examples: // ~~~~ contracts/IBar.sol IBar // ~~~~ contracts/MMERC20.sol MMERC20 // ~~~~ contracts/MMERC20.sol Bar // ~~~~ contracts/mock/foo/Foo.sol Foo // ~~~~ contracts/mock/foo/Foo.sol Foo2 // skip solidity interface contract if (bytecode === "0x") continue; // skip solidity library contract if (abi.length === 0) continue; // skip ignored contracts if (ignoreContracts.includes(name)) continue; // `contracts/MMERC20.sol MMERC20` -> `MMERC20` -> `["MMERC20"]` // `contracts/MMERC20.sol Bar` -> `MMERC20` -> `["Bar"]` // `contracts/mock/foo/Foo.sol Foo` -> `mock/foo/Foo` -> `["mock", "foo", "Foo"]` // `contracts/mock/foo/Foo.sol Foo2` -> `mock/foo/Foo` -> `["mock", "foo", "Foo2"]` let path = source.slice(10, source.length - 4).split("/"); path[path.length - 1] = name; // !! IMPORTANT: replace last element with contract name console.log("---- ", name, path); // examples: // ---- MMERC20 [ 'MMERC20' ] // ---- Bar [ 'Bar' ] // ---- Foo [ 'mock', 'foo', 'Foo' ] // ---- Foo2 [ 'mock', 'foo', 'Foo2' ] contracts.push({ name, path }); } return new Promise((resolve) => { resolve({ contracts, }); }); } export function paths2json( existsJson: any, contracts: { name: string; path: string[] }[], defaultValue: string, ): string { const result: any = {}; for (const contract of contracts) { if (contract.path.length == 1) { const key = contract.name; result[key] = existsJson[key] == null ? defaultValue : existsJson[key]; } else { // reset value at each loop let current = result; let currentExists = existsJson; for (let i = 0; i < contract.path.length; i++) { if (i == contract.path.length - 1) { const key = contract.name; current[key] = currentExists[key] == null ? defaultValue : currentExists[key]; } else { const key = contract.path[i]; current[key] = current[key] == null ? {} : current[key]; current = current[key]; currentExists = currentExists[key] == null ? {} : currentExists[key]; } } } } return JSON.stringify(result, null, 2); } export function flatJson(json: any): [string, string][] { const result: [string, string][] = []; for (const key in json) { if (typeof json[key] == "object") { const r = flatJson(json[key]); result.push(...r); } else { result.push([key, json[key]]); } } return result; }