UNPKG

@nomicfoundation/hardhat-verify

Version:
71 lines 3.86 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getMetadataSectionLength = exports.inferCompilerVersion = exports.MISSING_METADATA_VERSION_RANGE = exports.SOLC_NOT_FOUND_IN_METADATA_VERSION_RANGE = exports.METADATA_LENGTH = void 0; const debug_1 = __importDefault(require("debug")); const util_1 = __importDefault(require("util")); exports.METADATA_LENGTH = 2; exports.SOLC_NOT_FOUND_IN_METADATA_VERSION_RANGE = "0.4.7 - 0.5.8"; exports.MISSING_METADATA_VERSION_RANGE = "<0.4.7"; const log = (0, debug_1.default)("hardhat:hardhat-verify:metadata"); /** * Try to infer the Solidity compiler version from the bytecode metadata. * * Not all compiler releases produce the same bytecode: * Solc v0.4.7 was the first compiler to introduce metadata into the generated bytecode. * See https://docs.soliditylang.org/en/v0.4.7/miscellaneous.html#contract-metadata * Solc v0.4.26, the last release for the v0.4 series, does not feature the compiler version in its emitted metadata. * See https://docs.soliditylang.org/en/v0.4.26/metadata.html#encoding-of-the-metadata-hash-in-the-bytecode * Solc v0.5.9 was the first compiler to introduce its version into the metadata. * See https://docs.soliditylang.org/en/v0.5.9/metadata.html#encoding-of-the-metadata-hash-in-the-bytecode * Solc v0.6.0 features compiler version metadata. * See https://docs.soliditylang.org/en/v0.6.0/metadata.html#encoding-of-the-metadata-hash-in-the-bytecode */ function inferCompilerVersion(bytecode) { let solcMetadata; try { solcMetadata = decodeSolcMetadata(bytecode); } catch { // The decoding failed. Unfortunately, our only option is to assume that this bytecode was emitted by an old version. // Technically, this bytecode could have been emitted by a compiler for another language altogether. log("Could not decode metadata."); return exports.MISSING_METADATA_VERSION_RANGE; } if (solcMetadata instanceof Buffer) { if (solcMetadata.length === 3) { const [major, minor, patch] = solcMetadata; const solcVersion = `${major}.${minor}.${patch}`; log(`Solc version detected in bytecode: ${solcVersion}`); return solcVersion; } // probably unreachable log(`Found solc version field with ${solcMetadata.length} elements instead of three!`); } // The embedded metadata was successfully decoded but there was no solc version in it. log(`Could not detect solidity version in metadata.`); return exports.SOLC_NOT_FOUND_IN_METADATA_VERSION_RANGE; } exports.inferCompilerVersion = inferCompilerVersion; function getMetadataSectionLength(bytecode) { return bytecode.slice(-exports.METADATA_LENGTH).readUInt16BE(0) + exports.METADATA_LENGTH; } exports.getMetadataSectionLength = getMetadataSectionLength; /** * Decode the bytecode metadata and return the solc version. */ function decodeSolcMetadata(bytecode) { const { decodeFirstSync } = require("cbor"); const metadataSectionLength = getMetadataSectionLength(bytecode); // The metadata and its length are in the last few bytes of the bytecode. const metadataPayload = bytecode.slice(-metadataSectionLength, -exports.METADATA_LENGTH); log(`Read metadata length ${metadataSectionLength}`); const lastMetadataBytes = metadataPayload.slice(-100); log(`Last ${lastMetadataBytes.length} bytes of metadata: ${lastMetadataBytes.toString("hex")}`); const decodedMetadata = decodeFirstSync(metadataPayload, { required: true }); log(`Metadata decoded: ${util_1.default.inspect(decodedMetadata)}`); return decodedMetadata.solc; } //# sourceMappingURL=metadata.js.map