Semantic Web and Web 3.0 · class 11 · demo

The indexer: events become triples

Every LogCreated the contract emitted went through triples(event) of examples/06-indexer/events-to-triples.mjs — unchanged, in lib/: validated, then six triples per event, whose subject is the digest. onto:document is the same IRI the domain graph uses: that is the join.

The chain graph, as Turtle

19 triples in <https://data.csoares.me/graph/chain> — the highlighted one comes from the revocation notice. Raw: chain.ttl · chain.nt

@prefix onto: <https://data.csoares.me/onto#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix log: <https://data.csoares.me/log/> .
@prefix address: <https://data.csoares.me/address/> .
@prefix certificate: <https://data.csoares.me/certificate/> .
@prefix revocation: <https://data.csoares.me/revocation/> .

log:0x1d38a204cc9a92a2c898611a48b4ba77931ee6f964663d8adf7a41450a94aef7 a onto:OnChainRecord ;
    onto:documentDigest "0x1d38a204cc9a92a2c898611a48b4ba77931ee6f964663d8adf7a41450a94aef7" ;
    onto:document certificate:2026-001 ;
    prov:wasAttributedTo address:0x1111111111111111111111111111111111111111 ;
    onto:block 8412991 ;
    onto:transaction "0x5ebcd55cc8227ddeb1581e3611e7d9d04a9e436a98307f868721ffbe4d937c1d" .

log:0x559cc480db041ec6d3db8795727ff3a5132f87a8f1269f6d0aebef1890e5555a a onto:OnChainRecord ;
    onto:documentDigest "0x559cc480db041ec6d3db8795727ff3a5132f87a8f1269f6d0aebef1890e5555a" ;
    onto:document certificate:2026-002 ;
    prov:wasAttributedTo address:0x1111111111111111111111111111111111111111 ;
    onto:block 8412992 ;
    onto:transaction "0x607da5a1bb513cbe8be74c31fbaf572693c16fc596c1b9195ea11a3c5757203e" ;
    onto:revoked true .

log:0x736e394a86226f896b7fda931ce781f70f281ebcbeeb65610ddfb98c9eab42d6 a onto:OnChainRecord ;
    onto:documentDigest "0x736e394a86226f896b7fda931ce781f70f281ebcbeeb65610ddfb98c9eab42d6" ;
    onto:document revocation:2026-002 ;
    prov:wasAttributedTo address:0x1111111111111111111111111111111111111111 ;
    onto:block 8412994 ;
    onto:transaction "0xb8f20a8c7833b074ca5d2a5cf8d69001f20727b02986cae9d9689268081fd509" .

Event by event

LogCreated block 8412991 · tx 0x5ebcd5…937c1d

digest 0x1d38a204cc9a92a2c898611a48b4ba77931ee6f964663d8adf7a41450a94aef7
author 0x1111111111111111111111111111111111111111
uri   https://data.csoares.me/certificate/2026-001

<…/log/0x1d38…94aef7> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://data.csoares.me/onto#OnChainRecord> .
<…/log/0x1d38…94aef7> <https://data.csoares.me/onto#documentDigest> "0x1d38a204cc9a92a2c898611a48b4ba77931ee6f964663d8adf7a41450a94aef7" .
<…/log/0x1d38…94aef7> <https://data.csoares.me/onto#document> <https://data.csoares.me/certificate/2026-001> .
<…/log/0x1d38…94aef7> <http://www.w3.org/ns/prov#wasAttributedTo> <https://data.csoares.me/address/0x1111111111111111111111111111111111111111> .
<…/log/0x1d38…94aef7> <https://data.csoares.me/onto#block> "8412991"^^<http://www.w3.org/2001/XMLSchema#integer> .
<…/log/0x1d38…94aef7> <https://data.csoares.me/onto#transaction> "0x5ebcd55cc8227ddeb1581e3611e7d9d04a9e436a98307f868721ffbe4d937c1d" .

LogCreated block 8412992 · tx 0x607da5…57203e

digest 0x559cc480db041ec6d3db8795727ff3a5132f87a8f1269f6d0aebef1890e5555a
author 0x1111111111111111111111111111111111111111
uri   https://data.csoares.me/certificate/2026-002

<…/log/0x559c…e5555a> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://data.csoares.me/onto#OnChainRecord> .
<…/log/0x559c…e5555a> <https://data.csoares.me/onto#documentDigest> "0x559cc480db041ec6d3db8795727ff3a5132f87a8f1269f6d0aebef1890e5555a" .
<…/log/0x559c…e5555a> <https://data.csoares.me/onto#document> <https://data.csoares.me/certificate/2026-002> .
<…/log/0x559c…e5555a> <http://www.w3.org/ns/prov#wasAttributedTo> <https://data.csoares.me/address/0x1111111111111111111111111111111111111111> .
<…/log/0x559c…e5555a> <https://data.csoares.me/onto#block> "8412992"^^<http://www.w3.org/2001/XMLSchema#integer> .
<…/log/0x559c…e5555a> <https://data.csoares.me/onto#transaction> "0x607da5a1bb513cbe8be74c31fbaf572693c16fc596c1b9195ea11a3c5757203e" .

LogCreated block 8412994 · tx 0xb8f20a…1fd509

digest 0x736e394a86226f896b7fda931ce781f70f281ebcbeeb65610ddfb98c9eab42d6
author 0x1111111111111111111111111111111111111111
uri   https://data.csoares.me/revocation/2026-002

<…/log/0x736e…ab42d6> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://data.csoares.me/onto#OnChainRecord> .
<…/log/0x736e…ab42d6> <https://data.csoares.me/onto#documentDigest> "0x736e394a86226f896b7fda931ce781f70f281ebcbeeb65610ddfb98c9eab42d6" .
<…/log/0x736e…ab42d6> <https://data.csoares.me/onto#document> <https://data.csoares.me/revocation/2026-002> .
<…/log/0x736e…ab42d6> <http://www.w3.org/ns/prov#wasAttributedTo> <https://data.csoares.me/address/0x1111111111111111111111111111111111111111> .
<…/log/0x736e…ab42d6> <https://data.csoares.me/onto#block> "8412994"^^<http://www.w3.org/2001/XMLSchema#integer> .
<…/log/0x736e…ab42d6> <https://data.csoares.me/onto#transaction> "0xb8f20a8c7833b074ca5d2a5cf8d69001f20727b02986cae9d9689268081fd509" .

This event is a revocation notice: the demo's one extra rule marks the record of the certificate it names.

INSERT DATA {
  GRAPH <https://data.csoares.me/graph/chain> {
    <https://data.csoares.me/log/0x559cc480db041ec6d3db8795727ff3a5132f87a8f1269f6d0aebef1890e5555a> <https://data.csoares.me/onto#revoked> "true"^^<http://www.w3.org/2001/XMLSchema#boolean> .
  }
}

The update an indexer sends to the store

Replace, do not append: the same event can arrive twice (a restart, a reorganisation). This is updateSPARQL(event) for the first event — what indexer.mjs POSTs to Fuseki. Here the graph lives in memory.

DELETE WHERE { GRAPH <https://data.csoares.me/graph/chain> { <https://data.csoares.me/log/0x1d38a204cc9a92a2c898611a48b4ba77931ee6f964663d8adf7a41450a94aef7> ?p ?o } };
INSERT DATA {
  GRAPH <https://data.csoares.me/graph/chain> {
    <https://data.csoares.me/log/0x1d38a204cc9a92a2c898611a48b4ba77931ee6f964663d8adf7a41450a94aef7> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://data.csoares.me/onto#OnChainRecord> .
    <https://data.csoares.me/log/0x1d38a204cc9a92a2c898611a48b4ba77931ee6f964663d8adf7a41450a94aef7> <https://data.csoares.me/onto#documentDigest> "0x1d38a204cc9a92a2c898611a48b4ba77931ee6f964663d8adf7a41450a94aef7" .
    <https://data.csoares.me/log/0x1d38a204cc9a92a2c898611a48b4ba77931ee6f964663d8adf7a41450a94aef7> <https://data.csoares.me/onto#document> <https://data.csoares.me/certificate/2026-001> .
    <https://data.csoares.me/log/0x1d38a204cc9a92a2c898611a48b4ba77931ee6f964663d8adf7a41450a94aef7> <http://www.w3.org/ns/prov#wasAttributedTo> <https://data.csoares.me/address/0x1111111111111111111111111111111111111111> .
    <https://data.csoares.me/log/0x1d38a204cc9a92a2c898611a48b4ba77931ee6f964663d8adf7a41450a94aef7> <https://data.csoares.me/onto#block> "8412991"^^<http://www.w3.org/2001/XMLSchema#integer> .
    <https://data.csoares.me/log/0x1d38a204cc9a92a2c898611a48b4ba77931ee6f964663d8adf7a41450a94aef7> <https://data.csoares.me/onto#transaction> "0x5ebcd55cc8227ddeb1581e3611e7d9d04a9e436a98307f868721ffbe4d937c1d" .
  }
}

Nothing off the chain is trusted

Anyone can call register with any uri. Run now with uri = 'not a uri> } INSERT DATA { <a> <b> <c> } #', the indexer refuses:

invalid URI coming off the chain: not a uri> } INSERT DATA { <a> <b> <c> } #

An in-memory chain (the Ethereum virtual machine, @ethereumjs/evm), in this one process: no test network, no wallet, no keys, no money. Nothing a visitor does is kept.