Skip to content

Commit

Permalink
new writeMastercopyFromExplorer. Rename functions for clarity
Browse files Browse the repository at this point in the history
Co-authored-by: Julio Avila <[email protected]>
  • Loading branch information
cristovaoth and juliopavila committed Aug 14, 2024
1 parent dbe49af commit 73b57da
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import deployMastercopy from "../deploy/deployMastercopy";
import { EIP1193Provider, MastercopyArtifact } from "../types";

/**
* Iterates through each entry in the mastercopy artifacts file and deploys the mastercopy using the passed in provider.
* Iterates through each entry in the mastercopy artifacts file and deploys each mastercopy using the passed in provider.
* Entries that are already deployed will result in no operation.
*
* @param {Object} params - The function parameters.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,25 @@ import { resolveApiUrl } from "./chainConfig";
* @returns {Promise<{ ok: boolean; noop: boolean }>} The verification result.
* @throws {Error} If the API URL is unreachable, the API key is invalid, or the verification fails.
*/
export default async function verify(
{
contractName,
sourceName,
compilerVersion,
compilerInput,
address,
constructorArgs: { types, values },
}: {
contractName: string;
sourceName: string;
compilerVersion: string;
compilerInput: string;
address: string;
constructorArgs: { types: any[]; values: any[] };
},
apiUrlOrChainId: string,
apiKey: string
): Promise<{ ok: boolean; noop: boolean }> {
export async function verifySourceCode({
contractName,
sourceName,
compilerVersion,
compilerInput,
address,
constructorArgs: { types, values },
apiUrlOrChainId,
apiKey,
}: {
contractName: string;
sourceName: string;
compilerVersion: string;
compilerInput: string;
address: string;
constructorArgs: { types: any[]; values: any[] };
apiUrlOrChainId: string;
apiKey: string;
}): Promise<{ ok: boolean; noop: boolean }> {
const url = resolveApiUrl(apiUrlOrChainId);

if (!(await isLiveUrl(url))) {
Expand All @@ -64,7 +64,6 @@ export default async function verify(
sourceCode: JSON.stringify(compilerInput),
codeformat: "solidity-standard-json-input",
contractname: `${sourceName}:${contractName}`,
// contractname: contractName,
compilerversion: compilerVersion,
constructorArguements: AbiCoder.defaultAbiCoder()
.encode(types, values)
Expand Down Expand Up @@ -93,11 +92,15 @@ export default async function verify(
};
}

export async function retrieve(
address: string,
apiUrlOrChainId: string,
apiKey: string
) {
export async function getSourceCode({
address,
apiUrlOrChainId,
apiKey,
}: {
address: string;
apiUrlOrChainId: string;
apiKey: string;
}) {
const url = resolveApiUrl(apiUrlOrChainId);

if (!(await isLiveUrl(url))) {
Expand Down Expand Up @@ -138,28 +141,23 @@ export async function retrieve(
throw new Error(`Retrieve Error: ${status} ${message}`);
}

console.log("THE TYPE ABI " + typeof result[0].ABI);
console.log(JSON.parse(result[0].ABI));

console.log("THE TYPE SourceCode " + typeof result[0].SourceCode);
console.log(JSON.parse(result[0].SourceCode).trim().slice(1, -1));

const compilerInput = result[0].SourceCode as any;
const abi = safeJsonParse(result[0].ABI);
const compilerInput = safeJsonParse(result[0].SourceCode) as any;
const contractName = result[0].ContractName as string;
const sourceName = sourcePathFromSourceCode(compilerInput, contractName);

console.log("THE TYPE " + typeof result[0].ABI);

if (!sourceName) {
throw new Error(`Could not find source name for contract ${contractName}`);
throw new Error(
`Could not find a sourceName for contractName ${contractName}`
);
}

return {
compilerInput,
compilerVersion: result[0].CompilerVersion,
contractName,
sourceName,
abi: result[0].ABI,
abi,
};
}

Expand Down Expand Up @@ -260,3 +258,21 @@ async function isVerified(
function isOk(status: number): boolean {
return String(status) === "1";
}

/**
* Parses a JSON string, handling cases where the string may be
* improperly wrapped with extra braces `{}`.
*
* If the JSON is valid, it will be parsed directly.
*
*/
function safeJsonParse(input: string): any {
input = input.trim();

try {
return JSON.parse(input);
} catch {
input = input.replace(/^\{|\}$/g, "").trim();
return JSON.parse(input);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { MastercopyArtifact } from "../types";
* @returns {MastercopyArtifact} The Mastercopy artifact information.
* @throws {Error} If the artifacts file does not exist, the contract name is not found, or the contract version is invalid.
*/
export default function readMastercopyArtifact({
export default function readMastercopy({
contractName,
contractVersion,
mastercopyArtifactsFile = defaultMastercopyArtifactsFile(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { existsSync, readFileSync } from "fs";

import { MastercopyArtifact } from "../types";

import { defaultMastercopyArtifactsFile } from "./internal/paths";
import verify from "./internal/verify";
import { verifySourceCode } from "./internal/etherscan";

import { MastercopyArtifact } from "../types";

/**
* Iterates through each entry in the mastercopy artifacts file and verifies the mastercopy on an Etherscan-compatible block explorer.
Expand Down Expand Up @@ -38,11 +38,11 @@ export default async function ({
for (const [version, artifact] of Object.entries(
allArtifacts[contractName]
)) {
const { noop } = await verify(
artifact as MastercopyArtifact,
const { noop } = await verifySourceCode({
...(artifact as MastercopyArtifact),
apiUrlOrChainId,
apiKey
);
apiKey,
});

const { contractName, address } = artifact as MastercopyArtifact;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ import getBuildArtifact from "./internal/getBuildArtifact";
import { MastercopyArtifact } from "../types";

/**
* Extracts and stores current Mastercopy contract information in the artifacts file.
* Extracts and stores current Mastercopy result from current contract build, and stores it in the artifacts file.
*
* Optional fields such as `compilerInput` and `bytecode` can be provided externally or extracted from build artifacts.
* It is recommended to provide `compilerInput`, as the internal code will include all generated sources in the verification, rather than just the sources reached by the current contract through graph traversal.
*
* @param {Object} params - The function parameters.
Expand All @@ -31,12 +30,11 @@ import { MastercopyArtifact } from "../types";
* @param {string} [params.buildDirPath=defaultBuildDir()] - The path to the build directory. Optional.
* @param {string} [params.mastercopyArtifactsFile=defaultMastercopyArtifactsFile()] - The path to the mastercopy artifacts file. Optional.
*/
export default function extractAndWriteMastercopyArtifact({
export default function writeMastercopyFromBuild({
contractVersion,
contractName,
compilerInput: minimalCompilerInput,
factory = erc2470FactoryAddress,
bytecode,
constructorArgs,
salt,
buildDirPath = defaultBuildDir(),
Expand All @@ -45,7 +43,6 @@ export default function extractAndWriteMastercopyArtifact({
contractVersion: string;
contractName: string;
factory?: string;
bytecode?: string;
constructorArgs: { types: any[]; values: any[] };
salt: string;
compilerInput?: any;
Expand All @@ -70,11 +67,11 @@ export default function extractAndWriteMastercopyArtifact({
factory,
address: predictSingletonAddress({
factory,
bytecode: bytecode || buildArtifact.bytecode,
bytecode: buildArtifact.bytecode,
constructorArgs,
salt,
}),
bytecode: bytecode || buildArtifact.bytecode,
bytecode: buildArtifact.bytecode,
constructorArgs,
salt,
abi: buildArtifact.abi,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { address as erc2470FactoryAddress } from "../factory/erc2470Factory";
import predictSingletonAddress from "../encoding/predictSingletonAddress";

import { defaultMastercopyArtifactsFile } from "./internal/paths";
import { getSourceCode } from "./internal/etherscan";

import { MastercopyArtifact } from "../types";
import { retrieve } from "./internal/verify";

export default async function reconstructMastercopyArtifact({
export default async function writeMastercopyFromExplorer({
contractVersion,
factory = erc2470FactoryAddress,
address,
Expand All @@ -31,7 +31,7 @@ export default async function reconstructMastercopyArtifact({
mastercopyArtifactsFile?: string;
}) {
const { contractName, sourceName, compilerVersion, compilerInput, abi } =
await retrieve(address, apiUrlOrChainId, apiKey);
await getSourceCode({ address, apiUrlOrChainId, apiKey });

const mastercopies = existsSync(mastercopyArtifactsFile)
? JSON.parse(readFileSync(mastercopyArtifactsFile, "utf8"))
Expand Down
25 changes: 12 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ import deployProxy from "./deploy/deployProxy";

import predictSingletonAddress from "./encoding/predictSingletonAddress";

import readMastercopyArtifact from "./artifact/readMastercopyArtifact";
import writeMastercopyArtifact from "./artifact/writeMastercopyArtifact";
// temp
import reconstructMastercopyArtifact from "./artifact/reconstructMastercopyArtifact";
import deployMastercopiesFromArtifact from "./artifact/deployMastercopies";
import verifyMastercopiesFromArtifact from "./artifact/verifyMastercopies";
import writeMastercopyFromBuild from "./artifact/writeMastercopyFromBuild";
import writeMastercopyFromExplorer from "./artifact/writeMastercopyFromExplorer";
import readMastercopy from "./artifact/readMastercopy";
import deployAllMastercopies from "./artifact/deployAllMastercopies";
import verifyAllMastercopies from "./artifact/verifyAllMastercopies";

export {
// encoding
Expand All @@ -24,17 +23,17 @@ export {
encodeDeployProxy,
predictProxyAddress,

// deploy
// low-level tasks
deployFactories,
deployMastercopy,
deployProxy,

// artifact
readMastercopyArtifact,
writeMastercopyArtifact,
reconstructMastercopyArtifact,
deployMastercopiesFromArtifact,
verifyMastercopiesFromArtifact,
// mastercopy artifact helpers
writeMastercopyFromBuild,
writeMastercopyFromExplorer,
readMastercopy,
deployAllMastercopies,
verifyAllMastercopies,
};

import type { EIP1193Provider } from "./types";
Expand Down

0 comments on commit 73b57da

Please sign in to comment.