Come funziona
L'esempio di sempre: Elena compra da un negozio che non conosce. Paga 300 EURC, che restano vincolati finché il corriere non segna consegnato. Se dopo dieci giorni il pacco non è arrivato, i soldi tornano a lei.
I termini
Uno scontratto è fatto di sei cose:
| Campo | Cosa è |
|---|---|
payer |
Chi versa. Nell'esempio, Elena. |
payee |
Chi riceve. Nell'esempio, il negozio. |
money |
La somma, in EURC. Gli importi sono in unità minime, con 6 decimali: 300 EURC sono 300000000. |
condition |
Il fatto che esegue il contratto. |
deadline |
La scadenza, in secondi Unix. |
onExpiry |
Cosa succede alla scadenza se il fatto non c'è stato: refund, i soldi tornano a chi ha versato, o execute, si esegue comunque. |
Ogni parte ha un indirizzo, un nome da mostrare e il modo in cui è stata identificata. Oggi è wallet; domani kyc o cie.
La condizione
| Tipo | Chi la certifica | Nel pilota |
|---|---|---|
parcel-delivered |
il corriere, tramite AfterShip | sì |
manual-acceptance |
la parte indicata accetta la consegna | nel core, senza oracolo |
registry-fact |
un registro pubblico: PRA, Registro Imprese, SDI | nel core, senza oracolo |
Una condizione si osserva solo se c'è un oracolo che la sa leggere. Nel pilota c'è quello delle spedizioni. Gli altri tipi esistono nel modello, e il primo che arriva è l'accettazione con esecuzione tacita alla scadenza, il caso del freelance.
La condizione entra nel contratto come hash: keccak256 della sua forma canonica, con le chiavi in ordine. L'oracolo attesta quella condizione, non un pacco qualsiasi.
Il mandato
I termini diventano un documento EIP-712, il mandato: chi versa, chi riceve, token, importo, hash della condizione, scadenza, cosa fare alla scadenza, e un nonce casuale. Il suo hash è l'id dello scontratto, lo stesso nell'API e nel contratto.
Lo firmano le due parti, in due momenti:
- Chi riceve firma prima, fuori catena, dal suo wallet. Accetta quei termini e nessun altro.
- Chi versa firma versando. Apre lo scontratto sulla chain con la firma di chi riceve, poi versa. Il contratto controlla che la firma sia davvero di chi riceve, e su quei termini.
Il dominio della firma è { name: "Scontratto", version: "1", chainId, verifyingContract }: una firma vale per un solo escrow su una sola chain.
Dalla firma al pagamento
- Preparazione. Si preparano i termini e il mandato da far firmare.
- Firma di chi riceve. Lo scontratto nasce in stato
draft. - Apertura e versamento. Chi versa autorizza l'escrow a prelevare gli EURC, apre lo scontratto e versa. Lo stato passa a
funded. - Osservazione. Ogni cinque minuti, e subito quando AfterShip manda un aggiornamento, l'oracolo guarda il tracking.
- Attestazione. Se il corriere ha segnato consegnato prima della scadenza, l'attestatore firma quello che l'oracolo ha visto: l'id dello scontratto, l'hash della condizione e l'istante.
- Esecuzione. Con quella firma il contratto paga chi riceve. Lo stato passa a
executed. - Oppure la scadenza. Se il fatto non c'è stato, dopo la scadenza i soldi tornano a chi ha versato e lo stato passa a
refunded. CononExpiry: execute, invece, vanno a chi riceve.
Finché non ha versato, chi versa può rinunciare: sulla chain con cancel, e lo stato diventa cancelled. Nel pilota l'app e l'API non lo espongono ancora. Una bozza mai versata, comunque, non muove niente.
Oracolo e attestatore
L'oracolo guarda il fatto e lo riporta, con la prova: per una spedizione, lo stato del tracking su AfterShip, il corriere, la data di consegna. Non decide niente.
L'attestatore firma quello che l'oracolo ha visto. Il contratto rilascia i soldi solo con la firma dell'attestatore registrato nello scontratto al momento dell'apertura, e solo per un'osservazione fatta prima della scadenza.
Oggi l'attestatore è una chiave del nostro backend. È un attestatore fidato, non un oracolo pubblico: chi controlla quella chiave può rilasciare i fondi. Per il pilota va bene, ed è il motivo per cui oracolo e attestatore sono separati: la chiave può passare a un servizio terzo, o a una rete, senza toccare il resto.
Gli stati
| Stato | Cosa vuol dire |
|---|---|
draft |
Chi riceve ha firmato. Si aspetta il versamento. |
funded |
I soldi sono nel contratto. Si osserva la condizione. |
executed |
Pagato a chi riceve. |
refunded |
Scaduto senza il fatto: i soldi sono tornati a chi ha versato. |
cancelled |
Annullato da chi versa, prima del versamento. |
Ogni passaggio è un evento nella storia dello scontratto: created, funded, condition-met, executed, expired, refunded, cancelled. L'attestazione resta allegata, con la prova di quello che l'oracolo ha visto.