@nomicfoundation/hardhat-verify
Version:
Hardhat plugin for verifying contracts
71 lines • 3.86 kB
JavaScript
;
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