Skip to content
Closed
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- migrate:up

CREATE TABLE compiled_contracts_metadata (
compilation_id uuid PRIMARY KEY REFERENCES compiled_contracts(id) ON DELETE CASCADE,
metadata json NOT NULL
);

-- Backfill metadata from sourcify_matches.
-- We use DISTINCT ON (compilation_id) to ensure we only keep the "first" metadata variant per compilation,
-- which matches the logic used for source files. We also ensure we only insert metadata that is NOT NULL.
INSERT INTO compiled_contracts_metadata (compilation_id, metadata)
SELECT DISTINCT ON (vc.compilation_id)
vc.compilation_id,
sm.metadata
FROM sourcify_matches sm
JOIN verified_contracts vc ON vc.id = sm.verified_contract_id
WHERE sm.metadata IS NOT NULL
ON CONFLICT (compilation_id) DO NOTHING;

-- migrate:down

DROP TABLE IF EXISTS compiled_contracts_metadata;
29 changes: 28 additions & 1 deletion services/database/sourcify-database.sql
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,16 @@ CREATE TABLE public.compiled_contracts (
);


--
-- Name: compiled_contracts_metadata; Type: TABLE; Schema: public; Owner: -
--

CREATE TABLE public.compiled_contracts_metadata (
compilation_id uuid NOT NULL,
metadata json NOT NULL
);


--
-- Name: compiled_contracts_signatures; Type: TABLE; Schema: public; Owner: -
--
Expand Down Expand Up @@ -1317,6 +1327,14 @@ ALTER TABLE ONLY public.code
ADD CONSTRAINT code_pkey PRIMARY KEY (code_hash);


--
-- Name: compiled_contracts_metadata compiled_contracts_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.compiled_contracts_metadata
ADD CONSTRAINT compiled_contracts_metadata_pkey PRIMARY KEY (compilation_id);


--
-- Name: compiled_contracts compiled_contracts_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
Expand Down Expand Up @@ -2074,6 +2092,14 @@ ALTER TABLE ONLY public.compiled_contracts
ADD CONSTRAINT compiled_contracts_creation_code_hash_fkey FOREIGN KEY (creation_code_hash) REFERENCES public.code(code_hash);


--
-- Name: compiled_contracts_metadata compiled_contracts_metadata_compilation_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.compiled_contracts_metadata
ADD CONSTRAINT compiled_contracts_metadata_compilation_id_fkey FOREIGN KEY (compilation_id) REFERENCES public.compiled_contracts(id) ON DELETE CASCADE;


--
-- Name: compiled_contracts compiled_contracts_runtime_code_hash_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
Expand Down Expand Up @@ -2210,4 +2236,5 @@ INSERT INTO public.schema_migrations (version) VALUES
('20260309080000'),
('20260527081526'),
('20260527085036'),
('20260527085037');
('20260527085037'),
('20260816133800');
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ export default abstract class AbstractDatabaseService {
sourcesInformation: databaseColumns.sourcesInformation,
compilation_id: compiledContractId,
});

await this.database.insertCompiledContractMetadata(client, {
compilation_id: compiledContractId,
metadata: databaseColumns.metadata,
});
}

// insert new recompiled contract with newly added contract and compiledContract
Expand Down Expand Up @@ -214,6 +219,11 @@ export default abstract class AbstractDatabaseService {
sourcesInformation: databaseColumns.sourcesInformation,
compilation_id: compiledContractId,
});

await this.database.insertCompiledContractMetadata(client, {
compilation_id: compiledContractId,
metadata: databaseColumns.metadata,
});
}

// update verified contract with the newly added recompiled contract
Expand Down
29 changes: 27 additions & 2 deletions services/server/src/server/services/utils/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export class Database {
sourcify_matches.created_at,
sourcify_matches.creation_match,
sourcify_matches.runtime_match,
sourcify_matches.metadata,
COALESCE(compiled_contracts_metadata.metadata, sourcify_matches.metadata) as metadata,
verified_contracts.creation_values,
verified_contracts.runtime_values,
verified_contracts.compilation_id,
Expand All @@ -177,6 +177,7 @@ export class Database {
FROM ${this.schema}.sourcify_matches
JOIN ${this.schema}.verified_contracts ON verified_contracts.id = sourcify_matches.verified_contract_id
JOIN ${this.schema}.compiled_contracts ON compiled_contracts.id = verified_contracts.compilation_id
LEFT JOIN ${this.schema}.compiled_contracts_metadata ON compiled_contracts_metadata.compilation_id = verified_contracts.compilation_id
JOIN ${this.schema}.contract_deployments ON
contract_deployments.id = verified_contracts.deployment_id
AND contract_deployments.chain_id = $1
Expand Down Expand Up @@ -220,7 +221,12 @@ ${
onchain_runtime_code.code_hash,
onchain_creation_code.code_hash,
recompiled_runtime_code.code_hash,
recompiled_creation_code.code_hash`
recompiled_creation_code.code_hash${
properties.includes("metadata") ||
properties.includes("std_json_output")
? ",\n compiled_contracts_metadata.compilation_id"
: ""
}`
: "";

return await this.pool.query(
Expand All @@ -239,6 +245,11 @@ ${
LEFT JOIN ${this.schema}.code as onchain_creation_code ON onchain_creation_code.code_hash = contracts.creation_code_hash
LEFT JOIN ${this.schema}.code as recompiled_runtime_code ON recompiled_runtime_code.code_hash = compiled_contracts.runtime_code_hash
LEFT JOIN ${this.schema}.code as recompiled_creation_code ON recompiled_creation_code.code_hash = compiled_contracts.creation_code_hash
${
properties.includes("metadata") || properties.includes("std_json_output")
? `LEFT JOIN ${this.schema}.compiled_contracts_metadata ON compiled_contracts_metadata.compilation_id = verified_contracts.compilation_id`
: ""
}
${
properties.includes("function_signatures") ||
properties.includes("event_signatures") ||
Expand Down Expand Up @@ -1239,4 +1250,18 @@ ${
);
}
}

async insertCompiledContractMetadata(
poolClient: PoolClient,
{ compilation_id, metadata }: { compilation_id: string; metadata: any },
) {
if (metadata == null) return;

await poolClient.query(
`INSERT INTO ${this.schema}.compiled_contracts_metadata (compilation_id, metadata)
VALUES ($1, $2)
ON CONFLICT (compilation_id) DO NOTHING`,
[compilation_id, metadata],
);
}
}
7 changes: 5 additions & 2 deletions services/server/src/server/services/utils/database-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ export interface DatabaseColumns {
"id" | "compilation_id" | "deployment_id"
>;
sourcesInformation: SourceInformation[];
metadata: any;
}

export type GetVerifiedContractByChainAndAddressResult =
Expand Down Expand Up @@ -435,7 +436,8 @@ export const STORED_PROPERTIES_TO_SELECTORS = {
name: "compiled_contracts.name",
fully_qualified_name: "compiled_contracts.fully_qualified_name",
abi: "compiled_contracts.compilation_artifacts->'abi' as abi",
metadata: "sourcify_matches.metadata",
metadata:
"COALESCE(compiled_contracts_metadata.metadata, sourcify_matches.metadata) as metadata",
storage_layout:
"compiled_contracts.compilation_artifacts->'storageLayout' as storage_layout",
transient_storage_layout:
Expand All @@ -461,7 +463,7 @@ export const STORED_PROPERTIES_TO_SELECTORS = {
json_build_object(
split_part(compiled_contracts.fully_qualified_name, ':', -1), json_build_object(
'abi', compiled_contracts.compilation_artifacts->'abi',
'metadata', cast(sourcify_matches.metadata as text),
'metadata', cast(COALESCE(compiled_contracts_metadata.metadata, sourcify_matches.metadata) as text),
'userdoc', compiled_contracts.compilation_artifacts->'userdoc',
'devdoc', compiled_contracts.compilation_artifacts->'devdoc',
'storageLayout', compiled_contracts.compilation_artifacts->'storageLayout',
Expand Down Expand Up @@ -922,6 +924,7 @@ export async function getDatabaseColumnsFromVerification(
runtime_metadata_match,
creation_metadata_match,
},
metadata: (verification.compilation as any).metadata,
};
}

Expand Down