@matterlabs/hardhat-zksync-verify
Version:
Hardhat plugin to verify smart contracts for the ZKsync network
70 lines • 3.54 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSolcMetadataSectionLength = exports.decodeSolcMetadata = exports.inferSolcVersion = exports.METADATA_ABSENT_VERSION_RANGE = exports.METADATA_PRESENT_SOLC_NOT_FOUND_VERSION_RANGE = exports.METADATA_LENGTH_SIZE = void 0;
const debug_1 = __importDefault(require("debug"));
const util_1 = __importDefault(require("util"));
exports.METADATA_LENGTH_SIZE = 2;
exports.METADATA_PRESENT_SOLC_NOT_FOUND_VERSION_RANGE = '0.4.7 - 0.5.8';
exports.METADATA_ABSENT_VERSION_RANGE = '<0.4.7';
const log = (0, debug_1.default)('hardhat:hardhat-etherscan:metadata');
function inferSolcVersion(bytecode) {
let solcMetadata;
let metadataSectionSizeInBytes;
try {
const metadata = decodeSolcMetadata(bytecode);
log(`Metadata decoded: ${util_1.default.inspect(metadata.decoded)}`);
metadataSectionSizeInBytes = metadata.metadataSectionSizeInBytes;
solcMetadata = metadata.decoded.solc;
}
catch {
// The decoding failed. Unfortunately, our only option is to assume that this bytecode was emitted by an old version.
// This could also mean that contract has keccak metadata instead of ipfs.
log('Could not decode metadata.');
return {
metadataSectionSizeInBytes: 0,
solcVersion: exports.METADATA_ABSENT_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 { metadataSectionSizeInBytes, solcVersion };
}
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 {
metadataSectionSizeInBytes,
solcVersion: exports.METADATA_PRESENT_SOLC_NOT_FOUND_VERSION_RANGE,
};
}
exports.inferSolcVersion = inferSolcVersion;
function decodeSolcMetadata(bytecode) {
const metadataSectionLength = getSolcMetadataSectionLength(bytecode);
// The metadata and its length are in the last few bytes.
const metadataPayload = bytecode.slice(-metadataSectionLength, -exports.METADATA_LENGTH_SIZE);
log(`Read metadata length ${metadataSectionLength}`);
const lastMetadataBytes = metadataPayload.slice(-100);
log(`Last ${lastMetadataBytes.length} bytes of metadata: ${lastMetadataBytes.toString('hex')}`);
const { decodeFirstSync } = require('cbor');
// The documentation for decodeFirst mentions the `required` option even though
// the type information is missing it.
// See http://hildjj.github.io/node-cbor/Decoder.html#.decodeFirst
const decoded = decodeFirstSync(metadataPayload, { required: true });
return {
decoded,
metadataSectionSizeInBytes: metadataSectionLength,
};
}
exports.decodeSolcMetadata = decodeSolcMetadata;
function getSolcMetadataSectionLength(bytecode) {
return bytecode.slice(-exports.METADATA_LENGTH_SIZE).readUInt16BE(0) + exports.METADATA_LENGTH_SIZE;
}
exports.getSolcMetadataSectionLength = getSolcMetadataSectionLength;
//# sourceMappingURL=metadata.js.map