← Tots els articles

Núm. 04DNA Seed

Dos telèfons, noranta segons

A DNA Seed intercanvies el teu ADN en persona. Així és com l’app demana una trobada i no un enllaç, i el que demostra i el que no.

Vincent Porret

Cofundador i CEO · · 4 min de lectura

Estampa 04, Trena. Gotes i pintes sobre un bany, treta en construir el web.Passa-hi el punter per deixar caure tinta.

DNA Seed és un joc social que es juga en persona. Cada jugador porta un ADN, un codi que és només seu, i col·lecciona els codis de la gent que coneix. La regla que fa el joc és fàcil de dir i més difícil de construir: un intercanvi ha de passar cara a cara, no a través d’un enllaç que algú va reenviar.

El que vam descartar

Un codi QR permanent es pot fotografiar i publicar. Un enllaç per compartir viatja a qualsevol lloc. Una invitació a intercanviar a distància va contra la idea. Vam descartar els tres, juntament amb el codi QR tot sol, i també vam deixar el NFC. Va quedar un codi QR que viu noranta segons, i el Bluetooth.

Noranta segons

Quan tries rebre, una funció del servidor obre una sessió d’intercanvi: un token aleatori llarg, un nonce aleatori curt, i una caducitat d’aquí a noranta segons. La teva pantalla mostra el token i la caducitat com un codi QR, amb un compte enrere:

{ "v": 2, "type": "adn_exchange", "exchangeToken": "…", "expiresAt": "…" }

El codi no està signat i no cal que ho estigui. Només és una clau que el servidor busca, i el servidor es fia del seu propi rellotge i dels seus propis registres, no del codi. Al mateix temps, el teu telèfon comença a anunciar per Bluetooth un identificador de servei temporal, derivat del nonce. El nonce no és al codi QR: només viatja per l’aire.

L’altre telèfon ha de sentir el teu

La persona que tens davant escaneja el codi. El seu telèfon comprova que no ha caducat, i després escolta els telèfons propers durant set segons com a màxim. Només si en sent algun demana al servidor unir-se a la sessió, i el servidor comprova que va sentir el correcte. Després tots dos confirmeu a la pantalla, i només llavors es fa l’intercanvi. Si el Bluetooth està apagat o no té permís en algun dels dos telèfons, aquell telèfon ho diu i l’intercanvi no es pot fer. No hi ha manera de saltar-s’ho amb el codi QR sol.

Per ser precisos amb el que això demostra: el telèfon que escaneja ha d’estar a l’abast Bluetooth del telèfon que mostra el codi, dins d’una finestra de noranta segons, i tots dos jugadors han de dir que sí. L’abast Bluetooth no és una distància mesurada, i no diem que ho sigui.

A l’abast Bluetooth, en menys de noranta segons, i dos sís. Aquest és el llistó que vam posar.

El servidor escriu, els telèfons llegeixen

El servidor comprova la resta: la persona que escaneja ha iniciat sessió, la sessió existeix, no s’ha fet servir, no ha caducat, cosa que es torna a comprovar quan tots dos confirmeu, i ningú no escaneja el seu propi codi. Aquesta darrera regla s’aplica dues vegades, a la funció i amb una restricció a la base de dades. Els jugadors poden llegir els seus intercanvis i esborrar els seus, però mai crear-ne ni modificar-ne cap: la seguretat a nivell de fila deixa les insercions només a les funcions del servidor.

Un intercanvi fusiona les col·leccions en els dos sentits. Cada jugador rep a l’instant l’ADN de l’altre i, poc després, tots els altres codis que porta l’altre, des d’una cua al servidor. Un índex únic sobre portador i codi fa que la fusió sigui idempotent: un mateix codi no arriba mai dues vegades. Cada codi recorda a més qui el va passar i quants intercanvis va trigar a arribar, i això és el que dibuixa el seu arbre genealògic.

Un mapa sense GPS

El mapa mostra, país per país, fins on ha viatjat un ADN. L’app no llegeix mai la teva ubicació: el país és el que cada jugador declara al seu perfil. El mapa hi és per dir fins on va arribar un ADN, no on és ningú.

Tampoc no és un SDK de mapes. És un dibuix a mida en Flutter sobre els contorns de països de Natural Earth, en una simple projecció de longitud i latitud. Una dependència menys, i no es crida cap servei de mapes per dibuixar-lo.

Vincent