#!/usr/bin/env node // recompileaza-contract.mjs: arata ca AereAgentWallet2of2.json spune adevarul despre sursa lui (2026-09-29). Da intrarea standard a // compilatorului din artefact (sursele si setarile) unui solc 0.8.23 ales de cel care verifica, si cere ca codul de desfasurare si // codul de rulare sa iasa OCTET CU OCTET cele din artefact; codul de pe lant il compara apoi verifica-plati.mjs. Controlul metodei e // inauntru: aceeasi intrare cu un singur caracter schimbat intr-un comentariu al sursei TREBUIE sa dea alt cod (amprenta metadatelor), // altfel comparatia nu poate deosebi nimic si iesirea e NEMASURAT. // node recompileaza-contract.mjs --solc iesire 0 IDENTIC, 1 DIFERIT, 2 NEMASURAT // (solc 0.8.23: github.com/ethereum/solidity/releases/tag/v0.8.23, sau npx solc@0.8.23 cu --solcjs) import fs from 'node:fs'; import path from 'node:path'; import { spawnSync } from 'node:child_process'; import { fileURLToPath } from 'node:url'; import { incarcaArtefact } from './contract-2of2.mjs'; const a = process.argv.slice(2); const get = (f) => { const i = a.indexOf(f); return i >= 0 ? a[i + 1] : undefined; }; const solc = get('--solc'); const solcjs = a.includes('--solcjs'); if (!solc && !solcjs) { console.log('usage: node recompileaza-contract.mjs --solc | --solcjs (runs npx solc@0.8.23)'); process.exit(2); } const art = incarcaArtefact(); const cheama = (args, intrare) => solcjs ? spawnSync(process.platform === 'win32' ? 'npx.cmd' : 'npx', ['--yes', 'solc@0.8.23', ...args], { input: intrare, encoding: 'utf8', maxBuffer: 1 << 28, shell: process.platform === 'win32', timeout: 600000 }) : spawnSync(solc, args, { input: intrare, encoding: 'utf8', maxBuffer: 1 << 28, timeout: 600000 }); const ver = cheama(['--version']); const versiune = ((ver.stdout || '') + (ver.stderr || '')).match(/0\.8\.23\+commit\.[0-9a-f]+/); if (!versiune) { console.log(`NEMASURAT: the compiler is not solc 0.8.23 (${String((ver.stdout || ver.stderr || (ver.error && ver.error.message) || '').trim()).slice(0, 100)})`); process.exit(2); } const compileaza = (input) => { const r = cheama(['--standard-json'], JSON.stringify(input)); let o = null; try { o = JSON.parse(r.stdout); } catch { return { eroare: `no JSON from the compiler (exit ${r.status})` }; } const erori = (o.errors || []).filter((e) => e.severity === 'error'); if (erori.length) return { eroare: erori.map((e) => e.formattedMessage || e.message).join(' | ').slice(0, 200) }; const c = o.contracts && o.contracts[art.sourcePath] && o.contracts[art.sourcePath][art.contractName]; return c ? { bytecode: '0x' + c.evm.bytecode.object, deployedBytecode: '0x' + c.evm.deployedBytecode.object } : { eroare: 'the output has no such contract' }; }; const r = compileaza(art.standardJsonInput); if (r.eroare) { console.log(`NEMASURAT: ${r.eroare}`); process.exit(2); } // controlul metodei: un comentariu schimbat trebuie sa schimbe codul const alt = JSON.parse(JSON.stringify(art.standardJsonInput)); alt.sources[art.sourcePath].content = alt.sources[art.sourcePath].content.replace('HONEST SCOPE', 'HONEST SCOPF'); const rc = compileaza(alt); if (rc.eroare || alt.sources[art.sourcePath].content === art.standardJsonInput.sources[art.sourcePath].content || rc.deployedBytecode === r.deployedBytecode) { console.log(`NEMASURAT: the method control failed (a changed comment did not change the code${rc.eroare ? ': ' + rc.eroare : ''})`); process.exit(2); } // copia de citit a sursei (contract/AereAgentWallet2of2.sol, in pachetul publicat) trebuie sa fie chiar sursa compilata const citibil = path.join(path.dirname(fileURLToPath(import.meta.url)), 'contract', 'AereAgentWallet2of2.sol'); const copieBuna = !fs.existsSync(citibil) || fs.readFileSync(citibil, 'utf8').replace(/\r\n/g, '\n') === art.standardJsonInput.sources[art.sourcePath].content; const bun = r.bytecode === art.bytecode && r.deployedBytecode === art.deployedBytecode && copieBuna; console.log(` compiler: solc ${versiune[0]}${solcjs ? ' (solcjs)' : ''}`); console.log(fs.existsSync(citibil) ? ` ${copieBuna ? 'OK ' : 'FAIL'} contract/AereAgentWallet2of2.sol is the compiled source` : ' -- no readable copy of the source next to this script (contract/AereAgentWallet2of2.sol)'); console.log(` ${r.bytecode === art.bytecode ? 'OK ' : 'FAIL'} creation code: ${(r.bytecode.length - 2) / 2} bytes`); console.log(` ${r.deployedBytecode === art.deployedBytecode ? 'OK ' : 'FAIL'} runtime code: ${(r.deployedBytecode.length - 2) / 2} bytes`); console.log(` OK method control: one changed character in a comment gives another runtime code`); console.log(bun ? 'IDENTICAL: the artifact is the compilation of its source' : 'DIFFERENT: the artifact is not the compilation of its source, or the readable copy is not that source'); process.exitCode = bun ? 0 : 1;