Smart Contract per Escrow Notarile: Una Questione di Fiducia

Unnamed 2026 02 02T010948.575
…visualizzazioni

di Notaio Manlio Carlo Soldani

Iniziamo con una premessa onesta: l’escrow notarile tradizionale funziona. Funziona bene, funziona da secoli, e non c’è nessun problema urgente da risolvere.

Detto questo, mi sono comunque messo a studiare come uno smart contract potrebbe gestire una caparra confirmatoria in un preliminare di compravendita. Non per migliorare un sistema che funziona, ma per capire cosa cambia davvero quando le regole di rilascio dei fondi passano da un intermediario fiduciario a un codice informatico. E la risposta, come vedremo, è più interessante di quanto ci si aspetti — ma riguarda la struttura della fiducia, non la velocità delle transazioni.

L’Escrow Tradizionale: Come Funziona e Perché Funziona

Nel contesto più comune, ecco come gestisco una caparra confirmatoria.

Alice vende a Bob un appartamento per 500.000€. Firmano un preliminare di compravendita nel quale Bob versa una caparra confirmatoria di 50.000€. Il rogito definitivo è previsto tra sei mesi.

Le regole sono chiare, postate dal codice civile (art. 1385):

  • Se Bob recede senza giusta causa, perde la caparra: i 50.000€ vanno ad Alice.
  • Se Alice recede senza giusta causa, deve restituire il doppio: 100.000€ a Bob.
  • Se il rogito si perfeziona, la caparra viene imputata al prezzo.

Io, come notaio, ricevo la caparra in deposito. La custodisco in un conto dedicato. Quando si verifica una delle condizioni di rilascio — completamento della vendita, recesso di una parte, mancata verifica di una condizione sospensiva — dispongo il trasferimento alla parte avente diritto.

Punto e basta. È semplice, è sicuro, funziona.

La Domanda Giusta: Perché, Allora, uno Smart Contract?

Se il sistema funziona, perché esplorare alternativa tecnologiche? E soprattutto, perché non bastare un semplice bonifico istantaneo?

Questa è la domanda che vale la pena fare prima di scrivere una riga di codice. E la risposta passa per un ragionamento sulla natura della fiducia.

L’Input è Uguale

Pensateci. Quando il notaio rilascia la caparra nell’escrow tradizionale, compie un’azione: “svincollo i fondi in favore di questa parte”. Con uno smart contract, l’azione è la stessa: il notaio firma una transazione che attiva il rilascio. Il tempo di esecuzione è identico — anzi, nel caso tradizionale un bonifico istantaneo è più semplice, perché non richiede di creare e deployare un contratto su blockchain, di gestire wallet, di convertire fondi in stablecoin.

Se il punto fosse solo la velocità o la semplicità, lo smart contract perderebbe senza discussione.

Ma la Velocità Non è il Punto

Il punto è diverso. È una questione strutturale di fiducia.

Nel sistema tradizionale, i fondi sono nella disponibilità del notaio. Io ho la custodia, io svincolo, io dispongo. Se le parti si fidano di me — e nel contesto notarile, questa fiducia è giustificata dalla nostra funzione pubblica, dalla nostra responsabilità, dalla nostra posizione istituzionale — tutto funziona perfettamente.

Ma cosa succede se quella fiducia non c’è? O meglio: cosa succede in un contesto dove l’intermediario che gestisce i fondi non è un notaio, ma qualcuno nei confronti del quale le parti non hanno quella stessa garanzia istituzionale?

Qui lo smart contract diventa interessante.

Il Contesto Trustless

Immaginate un preliminare di compravendita gestito da un agente immobiliare. Le parti firmano, l’agente raccoglie la caparra. Ma l’agente non è un pubblico ufficiale. Non ha la stessa responsabilità istituzionale che ha il notaio. Le parti possono fidarsi di lui — spesso lo fanno — ma quella fiducia non è garantita da nessuna struttura pubblica.

In questo contesto, lo smart contract offre qualcosa di concreto: le regole di rilascio dei fondi non dipendono dalla buona volontà di un intermediario, ma da codice verificabile e deterministe. Se la condizione è soddisfatta, i fondi si muovono. Nessuno può bloccarli, nessuno può divertirli. Il codice non tradisce.

Questo è il significato di un sistema trustless: un sistema che non richiede fiducia in un’autorità centrale per funzionare correttamente.

Il Notaio come Supervisore della Delega

Ed è qui che il ruolo del notaio diventa, paradossalmente, ancora più centrale.

Se lo smart contract funziona meglio proprio in contesti dove la fiducia in un intermediario è assente o debole, allora chi garantisce che lo smart contract sia implementato correttamente? Chi verifica che il codice faccia davvero quello che le parti hanno negoziato? Chi assicura la conformità legale?

Il notaio.

Non come esecutore diretto dei trasferimenti, ma come supervisore della delega di fiducia allo smart contract stesso. Le parti decidono di affidare la gestione della caparra al codice. Il notaio è quello che verifica che quel codice sia corretto, che le regole codificate corrispondano alla volontà delle parti e alla legge, e che tutto sia formalmente valido.

La fiducia non viene eliminata. Viene spostata: dal notaio come custodiano dei fondi, al notaio come garante della correttezza dello strumento che custodierà i fondi al posto suo.

È una delega al codice, supervisionata dal fiduciario.

Il Caso d’Uso: Un Preliminare Gestito Senza Intermediario Fiduciario

Prendiamo un caso concreto che illustra questa logica.

Alice e Bob firmano un preliminare nel mio studio. La caparra è di 50.000€. Il rogito è tra sei mesi. Le condizioni sono standard: Bob deve ottenere il mutuo (condizione sospensiva), altrimenti il preliminare si risolve e la caparra torna indietro.

La novità: Alice e Bob preferiscono che la caparra sia gestita da uno smart contract piuttosto che da un deposito notarile tradizionale. Forse hanno letto degli smart contract, forse vogliono sperimentare, forse hanno semplicemente deciso di delegare la custodia ai fondi a uno strumento automatizzato. Non cambia: è un diritto che possono esercitare.

Il mio ruolo cambia in modo specifico: non custodisco più i fondi, ma verifico e supervisiono lo smart contract che lo farà al loro posto.

Fase 0: Preparazione

Nel mio studio, prima di tutto, verifico le identità delle parti, conduciamo il controllo AML/CFT, redigo il preliminare. Come sempre.

In più, devo spiegare alle parti come funziona lo smart contract: cosa significa che i fondi saranno bloccati nel contratto, come avvengono i rilasci, quali sono i rischi (ne parleremo dopo). Devo anche verificare che entrambe abbiano la capacità pratica di gestire un wallet crypto.

Fase 1: Il Preliminare

Redigo un preliminare classico. L’unica differenza è una clausola che stabilisce come la caparra verrà depositata e come i rilasci avverranno. L’indirizzo dello smart contract viene inserito nell’atto una volta deployato.

Fase 2: Deploy dello Smart Contract

Il contratto viene creato sulla blockchain Polygon — una rete Layer 2 di Ethereum, con fee molto basse — con i parametri che derivano direttamente dal preliminare:

// Parametri di inizializzazione
address payable seller;          // Alice
address payable buyer;           // Bob
address notary;                  // Notaio (supervisore)
IERC20 token;                    // EUROC (stablecoin, 1:1 con euro)
uint256 depositAmount;           // 50.000 EUROC
uint256 deadline;                // Timestamp del termine per il rogito
bytes32 preliminaryDeedHash;     // Hash IPFS del preliminare firmato

Il contratto viene verificato su PolygonScan: il codice sorgente è pubblico e chiunque — io, le parti, chiunque — può leggerlo e verificarne il funzionamento.

Fase 3: Deposito della Caparra

Bob trasferisce i 50.000 EUROC nel contratto. I fondi sono ora bloccati: né Alice, né Bob, né il notaio possono prenderli unilateralmente. L’unico modo per far muovere i fondi è che si verifichi una delle condizioni codificate nel contratto.

function depositFunds() external {
    require(msg.sender == buyer, "Solo l'acquirente può depositare");
    require(state == State.AWAITING_DEPOSIT, "Stato non valido");

    token.safeTransferFrom(msg.sender, address(this), depositAmount);

    state = State.DEPOSIT_LOCKED;
    depositTimestamp = block.timestamp;

    emit DepositReceived(msg.sender, depositAmount, block.timestamp);
}

Dopo il deposito, il notaio conferma on-chain che il preliminare è stato firmato regolarmente e che il deposito corrisponde:

function notaryConfirmDeposit() external {
    require(msg.sender == notary, "Solo il notaio");
    require(state == State.DEPOSIT_LOCKED, "Stato non valido");

    state = State.ACTIVE;
    emit NotaryConfirmed(block.timestamp);
}

Da questo punto in poi il contratto è attivo. I fondi sono bloccati. Le regole sono nel codice.

Fase 4: Gli Scenari di Rilascio

Il contratto gestisce tutti gli scenari previsti dal preliminare. Vediamoli uno per uno.

Vendita completata. Il rogito si perfeziona. Il notaio, dopo la firma del rogito definitivo, attiva il rilascio della caparra in favore di Alice (imputata al prezzo):

function completeSale(bytes32 _finalDeedHash) external {
    require(msg.sender == notary, "Solo il notaio");
    require(state == State.ACTIVE, "Stato non valido");
    require(_finalDeedHash != bytes32(0), "Hash rogito non valido");

    state = State.COMPLETED;
    finalDeedHash = _finalDeedHash;

    token.safeTransfer(seller, depositAmount);

    emit SaleCompleted(seller, depositAmount, _finalDeedHash, block.timestamp);
}

Bob recede. Bob decide di non procedere alla compravendita senza giusta causa. Chiama direttamente la funzione di recesso — non serve aspettare che qualcuno disponga il trasferimento. La caparra va ad Alice automaticamente:

function buyerWithdraw(string calldata _reason) external {
    require(msg.sender == buyer, "Solo l'acquirente");
    require(state == State.ACTIVE, "Stato non valido");
    require(block.timestamp <= deadline, "Termine scaduto");

    state = State.BUYER_WITHDREW;

    token.safeTransfer(seller, depositAmount);

    emit BuyerWithdrew(msg.sender, block.timestamp, _reason);
}

Alice recede. Alice decide di non procedere senza giusta causa. Per legge deve restituire il doppio della caparra. Il contratto lo gestisce: Alice deve aggiungere altri 50.000 EUROC, e il totale (100.000) va a Bob:

function sellerWithdraw(string calldata _reason) external {
    require(msg.sender == seller, "Solo il venditore");
    require(state == State.ACTIVE, "Stato non valido");
    require(block.timestamp <= deadline, "Termine scaduto");

    state = State.SELLER_WITHDREW;

    // Alice aggiunge un importo pari alla caparra
    token.safeTransferFrom(msg.sender, address(this), depositAmount);

    // Il doppio va a Bob
    token.safeTransfer(buyer, depositAmount * 2);

    emit SellerWithdrew(msg.sender, buyer, depositAmount * 2, block.timestamp, _reason);
}

Condizione sospensiva non verificata. Bob non ottiene il mutuo. Il notaio, dopo aver verificato la situazione, attiva la risoluzione del contratto e la restituzione integrale della caparra a Bob:

function cancelForSuspensiveCondition(string calldata _reason) external {
    require(msg.sender == notary, "Solo il notaio");
    require(state == State.ACTIVE, "Stato non valido");

    state = State.CANCELLED_SUSPENSIVE;

    token.safeTransfer(buyer, depositAmount);

    emit SuspensiveConditionFailed(_reason, block.timestamp);
}

Timeout. Passano sei mesi senza che il rogito si perfeziona e senza che una parte receda formalmente. Il termine scade. Chiunque può attivare questa funzione dopo la scadenza — non serve un consenso, è un fatto oggettivo:

function handleTimeout() external {
    require(block.timestamp > deadline, "Termine non ancora scaduto");
    require(state == State.ACTIVE, "Stato non valido");

    state = State.TIMEOUT;

    token.safeTransfer(buyer, depositAmount);

    emit TimeoutReached(block.timestamp);
}

Fase 5: Controversie

Se le parti non sono d’accordo su cosa sia successo — per esempio, Bob sostiene che Alice ha violato degli obblighi, Alice nega — il contratto prevede un meccanismo di disputa con un arbitro designato:

function initiateDispute(string calldata _reason) external {
    require(msg.sender == buyer || msg.sender == seller, "Solo le parti");
    require(state == State.ACTIVE, "Stato non valido");

    state = State.DISPUTE;
    dispute.initiator = msg.sender;
    dispute.reason = _reason;
    dispute.initiatedAt = block.timestamp;

    emit DisputeInitiated(msg.sender, _reason, block.timestamp);
}

function resolveDispute(address _winner) external {
    require(msg.sender == arbitrator, "Solo l'arbitro");
    require(state == State.DISPUTE, "Nessuna disputa attiva");
    require(
        _winner == buyer || _winner == seller || _winner == address(0),
        "Indirizzo non valido"
    );

    state = State.DISPUTE_RESOLVED;

    if (_winner == buyer) {
        token.safeTransfer(buyer, depositAmount);
    } else if (_winner == seller) {
        token.safeTransfer(seller, depositAmount);
    } else {
        // Nessun vincitore designato: split 50/50
        token.safeTransfer(buyer, depositAmount / 2);
        token.safeTransfer(seller, depositAmount / 2);
    }

    emit DisputeResolved(_winner, depositAmount, block.timestamp);
}

L’arbitro può essere un altro notaio, un organismo di mediazione, chiunque le parti abbiano designato nel preliminare. Il punto è che la decisione finale resta nelle mani di un umano — il codice non può interpretare “giusta causa”.

La Macchina a Stati: Come il Contratto Pensa

Il contratto opera come una macchina a stati finiti. Ogni stato ha regole precise su chi può fare cosa e verso quale stato si può transitare:

[CREATED]
    ↓  buyer deposita
[DEPOSIT_LOCKED]
    ↓  notaio conferma
[ACTIVE]
    ├──→ notaio completa rogito     → [COMPLETED]
    ├──→ buyer recede               → [BUYER_WITHDREW]
    ├──→ seller recede              → [SELLER_WITHDREW]
    ├──→ notaio: condiz. sospensiva → [CANCELLED_SUSPENSIVE]
    ├──→ timeout scade              → [TIMEOUT]
    └──→ disputa                    → [DISPUTE] → [DISPUTE_RESOLVED]

Ogni transizione è regolata da tre elementi: le condizioni che devono essere vere (i require), gli effetti che si producono (cambio di stato, trasferimento fondi), e gli eventi che vengono emessi (log immutabili sulla blockchain).

Aspetti Tecnici: Sicurezza e Ottimizzazioni

Un contratto che gestisce fondi reali deve essere scritto con massima attenzione alla sicurezza. Vediamo i pattern principali.

Reentrancy Protection

Il rischio di reentrancy è il più pericoloso nei contratti che gestiscono fondi. Un contratto malizioso può chiamare ripetutamente una funzione prima che questa finisca l’esecuzione, prelevando fondi più volte. La soluzione è un mutex:

bool private locked;

modifier noReentrant() {
    require(!locked, "No re-entrancy");
    locked = true;
    _;
    locked = false;
}

function completeSale(bytes32 _finalDeedHash) external noReentrant {
    // ... logica della funzione
}

Checks-Effects-Interactions

Il pattern standard per strutturare le funzioni che modificano stato e trasferiscono fondi: prima verifichi le condizioni, poi cambi lo stato interno, poi chiami contratti esterni. Così, anche se un chiamata esterna tenta un rientro, lo stato è già aggiornato:

function buyerWithdraw(string calldata _reason) external {
    // 1. CHECKS
    require(msg.sender == buyer, "Solo l'acquirente");
    require(state == State.ACTIVE, "Stato non valido");

    // 2. EFFECTS
    state = State.BUYER_WITHDREW;

    // 3. INTERACTIONS
    token.safeTransfer(seller, depositAmount);
}

Access Control

Ogni funzione deve essere chiamabile solo da chi ha il diritto di chiamarla. Usiamo modifier per questo:

modifier onlyNotary() {
    require(msg.sender == notary, "Solo il notaio");
    _;
}

modifier onlyParties() {
    require(msg.sender == buyer || msg.sender == seller, "Solo le parti");
    _;
}

modifier inState(EscrowState _expected) {
    require(state == _expected, "Stato non valido");
    _;
}

Gas Optimization

Ogni operazione sulla blockchain costa gas. Le ottimizzazioni principali per un contratto di questa dimensione:

// Gli eventi costano molto meno dello storage per loggare informazioni
event DepositReceived(address indexed from, uint256 amount, uint256 timestamp);

// Le variabili piccole vengono "packed" in un singolo slot da 32 byte
// address (20 byte) + uint96 (12 byte) = 32 byte = 1 slot
address seller;
uint96 depositAmount;

Aspetti Legali

Validità dello Smart Contract in Italia

Il Decreto Semplificazioni (D.L. 135/2018, convertito in L. 12/2019) definisce lo smart contract come “un programma per elaboratore che opera su tecnologie basate su registri distribuiti e la cui esecuzione vincola automaticamente due o più parti sulla base di effetti predefiniti dalle stesse” e stabilisce che gli smart contract possono soddisfare il requisito della forma scritta, previa identificazione informatica delle parti.

Questo significa che lo smart contract può avere rilevanza giuridica, ma non da solo. Serve sempre un contratto tradizionale — il preliminare — che esprime la volontà delle parti. Lo smart contract è lo strumento di esecuzione, non il titolo giuridico.

GDPR e Blockchain

La blockchain è immutabile. Il GDPR prevede il diritto all’oblio. Questa tensione si risolve non memorizzando dati personali on-chain, ma solo hash dei documenti. I documenti reali risiedono off-chain (su IPFS, nel caso di questo progetto), e possono essere gestiti nel rispetto della normativa sulla protezione dei dati.

Legge Applicabile e Giurisdizione

Il contratto preliminare specifica espressamente la legge applicabile e il foro competente. Lo smart contract esegue ciò che il preliminare prescrive: non introduce ambiguità giuridiche, ma le eredita dalla volontà delle parti.

I Rischi. Vanno Detti.

Sarebbe irresponsabile parlare di smart contract per escrow senza parlare dei rischi reali. E sono significativi.

Bug nel Codice

Questo è il rischio più serio. Un errore nel contratto può portare a perdita di fondi, e a differenza di un errore umano nell’escrow tradizionale, un bug nello smart contract è immutabile: non si può “correggere” un contratto già deployato. Il caso più famouso resta The DAO hack del 2016, dove circa 50 milioni di dollari sono stati sottratti per un singolo errore nel codice.

La mitigazione è l’audit professionale — obbligatorio, non opzionale — e il testing estensivo su reti di prova prima del deployment.

Perdita delle Chiavi Private

Se Bob perde le chiavi del suo wallet, non può più interagire con il contratto. I fondi restano bloccati per sempre. Non c’è un “recupero account” come con una banca.

La mitigazione è l’educazione e la gestione corretta delle chiavi (seed phrase, backup sicuri). Niente di più.

Complessità vs Semplicitá

Un bonifico istantaneo è più semplice. Un contratto su blockchain richiede wallet, stablecoin, comprensione del meccanismo. Per una singola caparra, la complessità aggiuntiva è notevole e deve essere giustificata dalla specifica situazione delle parti.

Ambiguità che il Codice Non Può Risolvere

Il codice è deterministico. Non può interpretare “giusta causa di recesso”, non può valutare se un vizio nell’immobile è “grave” o meno. Queste valutazioni restano in capo a un umano — il notaio, nell’eventualità di una controversia, o l’arbitro nel meccanismo di disputa.

Quando Ha Senso, Quando No

Alla fine dei conti, la domanda pratica è questa: quando vale la pena usare uno smart contract per una caparra?

Ha senso quando le parti preferiscono delegare la custodia dei fondi a regole automatizzate piuttosto che a un intermediario. Questo può avvenire perché l’intermediario naturale non è un pubblico ufficiale (agente immobiliare, mediatore privato), perché le parti vogliono trasparenza totale sul destino dei fondi, o semplicemente perché preferiscono un sistema dove nessuno possa intervenire unilateralmente sui fondi.

Non ha senso quando il sistema tradizionale funziona e le parti si fidano del notaio come custodiano. In quel caso, la complessità aggiuntiva dello smart contract non aggiunge valore.

Il notaio, in questo scenario, non viene sostituito. Cambia ruolo: da custode dei fondi a supervisore dello strumento che li custodierà. Verifica che il codice sia corretto. Certifica che le regole codificate corrispondano a quelle del preliminare. Resta l’unico punto di contatto per le valutazioni giuridiche che il codice non può fare.

La tecnologia non sostituisce la fiducia notarile. La rafforza, in quei contesti dove la fiducia viene delegata al codice stesso — sotto supervisione del fiduciario.


Notaio Manlio Carlo Soldani
Studio Notarile — Via Camillo Prampolini n. 14, Domodossola
Iscritto al Collegio Notarile di Verbania
Email: domodossola@notaiosoldani.it
Tel: 0324 066077


Articolo pubblicato il 31 Gennaio 2026

Tag: #SmartContracts #Blockchain #Escrow #TecnologiaNotarile #Polygon #Solidity #DirittoCivile #LegalTech


Nota tecnica: il codice presentato è semplificato a scopo didattico. Un’implementazione reale richiederebbe audit di sicurezza professionale e testing estensivo prima di qualsiasi uso con fondi reali.

 


Il presente articolo ha carattere generale e informativo, non costituisce parere legale personalizzato e non sostituisce la consulenza diretta con un notaio. Per assistenza specifica relativa alla vostra situazione, vi invitiamo a contattare il nostro Studio per fissare un appuntamento.  Contenuto generato con sistemi di Intelligenza Artificiale e supervisionato da professionisti dello Studio Notarile, in conformità ai requisiti di trasparenza del Regolamento UE 2024/1689 (AI Act).

 

Condividi

Esplora le aree dello Studio