Oracle Database Blockchain table

luca bindi
6 min readApr 22, 2020

Sul Database 21c, disponibile al momento in preview sul cloud Oracle di seconda generazione, il concetto di converged database è stato ulteriormente esteso.

Come spero molti sanno è possibile già dalle versioni precedenti utilizzare il database Oracle non solo come un database relazionale , Oracle Database è un converged database che permette di essere utilizzato anche ad esempio come

  • un classico NoSql che mediante chiamate API o REST permette di creare collection e inserire documenti
  • sfruttare tutta la potenzialità Oracle etc etc per dati in formato JSON dunque schemaless
  • esporre i dati in formato REST e usare tutti i verbi CRUD.
  • arricchire i dati o gestire dati geo posizionali
  • creare Grafi (sia Property Graph che RDF) sui dati presenti nel database
  • creare Modelli di machine learning
  • leggere direttamente messaggi da topic Kafka
  • sfruttare la multitenant per il devops , la CI/CD e specializzare ogni pluggable database come un polyglot persistent , oppure per fast deploy di un database con già tutto il codice applicativo che deve essere presente e avendo il controllo/ il versioning del codice
  • Leggere dati che risiedono su object-storage , o su HDFS e magari già tipizzati da hive
  • Possibilità di accedere contemporaneamente ai dati in memoria sia mediante una rappresentazione del dato per rows ( ottimizzato per OLTP) che per colonna (ottimizzato per accessi o interrogazioni analitiche)
  • Gestire dunque workload differenti sugli stessi dati ( transazionale e analitico = HTAP)
  • Gestire e supportare enormi inserimenti real time di dati (key value ) provenienti ad esempio da device IOT
  • e tanto tanto altro .

Questo logicamente si integra con tutto quello che negli anni Oracle ha implementato per quanto riguarda le performance ( optimizer , indicizzazione, automatic index, partitioning , InMemory , offloading Exadata ,etc ); La sicurezza ( TDE , encryption , vault , audit,etc); La disponibilità del dato (RAC ,Data Guard , GoldenGate, sharding, backup etc );La compression (basic, oltp , hcc etc ) e tutto questo è presente sia on-premise che nel Oracle Cloud , sia pubblico che at customer.

E’ scontato (e vale solo per il database Oracle :-) ) che tutti queste tipi differenti di dato e fonti possono interagire tra di loro per fornire informazioni, arricchirle in real time che sono fondamentali per il business.

Adesso però torniamo a vedere come usare la blockchain dentro il database mediante l’uso di tabelle.

Le blockchain sono elenchi di record , blocchi, espandibili collegati tra loro utilizzando metodi crittografici, ogni record contiene in genere un hash crittografato e sicuro che lo collega al blocco precedente più una serie di informazioni (timestamp e informazioni di transazione) che vengono aggiunti come colonne non visibili alla tabella (ma interrogabili dalle viste di sistema).

I record all’interno della blockchain non sono modificabili e neanche cancellabili se non a seguito di determinate condizioni .

Sul database Oracle 20c è possibile creare tabella di tipo blockchain dove i dati possono essere solamente inseriti (solo INSERT) e nessuna ulteriore manipolazione e’ permessa.

Vediamo come costruire su un database 20c una tabella di tipo blockchain

CREATE  BLOCKCHAIN  TABLE block_chain_table_test
( order_id number(12) primary key,
customer_name varchar2(100),
customer_id number(12),
order_date date,
order_value number(8,2),
currency varchar2(100),
channel varchar2(20)
)
NO DROP UNTIL 60 DAYS IDLE
NO DELETE LOCKED
HASHING USING "SHA2_512" VERSION "v1";
Con l’opzione “DROP UNTIL number DAYS IDLE” indichiamo che la tabella non può essere rimossa se non dopo 60 giorni di nessun nuovo insert.Con l’opzione “NO DELETE” LOCKED or NO DELETE UNTIL.. indichiamo che la retention sopra non puo’ essere alterata oppure non puo’ essere se non dopo un periodoNell’esempio sopra , la tabella può essere eliminata al più dopo 60 giorni di inattività(l’impostazione di default è 16). Le singole righe non possono essere eliminate

Viste del dizionario utili per check delle tabelle di tipo blockchain

USER (ALL | DBA | CDB) _BLOCKCHAIN_TABLES--come detto oltre alle colonne da noi stabilite nella create table, ci sono ulteriori 10 colonne nascosteselect column_name,hidden_column from user_tab_cols where table_name='BLOCK_CHAIN_TABLE_TEST';

Le operazioni di insert sono le classiche operazioni DML

insert into block_chain_table_test (order_id,customer_name,order_value) values (1,'Marco',1000);insert into block_chain_table_test (order_id,customer_name,order_value) values (2,'Anna',1000);insert into block_chain_table_test (order_id,customer_name,order_value) values (3,'Luca',1000);

Vale lo stesso per le operazioni di commit rollback

commit/ rollback;

Le operazioni di delete update e drop (tranne dopo i giorni indicati) non sono consentite

---error
delete block_chain_table_test where order_id=1;
--- error
update block_chain_table_test set customer_name='xxxxx' where order_id=1;
---error
drop table block_chain_table_test;

Le interrogazioni possono avvenire come ogni tabella mediante SQL standard

select * from block_chain_table_test;

ed inoltre la tabella può essere esposta via REST per permettere di utilizzare i verbi standard come GET(query) che POST (insert).

Verifica integrita blockchain table

Si può utilizzare un package per effettuare la verifica dell’integrità di tutte le righe su tutte le catene , e opzionalmente anche la signature.

Se l’integrità della catena dovesse risultare compromessa viene generata un eccezione.

DECLARE
verified_rows number:=0;
BEGIN
DBMS_BLOCKCHAIN_TABLE.VERIFY_ROWS(schema_name=>'TEST',table_name=>'BLOCK_CHAIN_TABLE_TEST',
number_of_rows_verified=>verified_rows,verify_signature=>TRUE);
DBMS_OUTPUT.PUT_LINE('Number of rows verified='||Verified_rows );
END;
/

Aggiunta di una firma al record

Possiamo anche aggiungere la nostra firma al record che abbiamo inserito nella blockchain table

Per farlo , all’interno di una cartella di lavoro generiamo una chiave rsa e un certificato per questa chiave

cd /u02/Key
---Genero una chiave rsa (CAroot.key)
openssl genrsa -out CAroot.key 2048
---Genero un certificato per questa chiave (CAroot.csr)
openssl req -x509 -days 730 -sha256 -nodes -key CAroot.key -days 730 -out CAroot.csr

Mappiamo questa cartella presente sul nostro DB server mediante l’oggetto Directory; Dopodiché aggiungiamo il certificato X.509 CAroot.csr per la signature

create or replace directory BLOCK as '/u02/Key';DECLARE
file_crs BFILE;
buffer BLOB;
amount NUMBER := 32767;
cert_guid RAW(16);
BEGIN
file_crs := BFILENAME('BLOCK', 'CAroot.csr');
DBMS_LOB.FILEOPEN(file_crs);
DBMS_LOB.READ(file_crs, amount, 1, buffer);
DBMS_LOB.FILECLOSE(file_crs);
DBMS_USER_CERTS.ADD_CERTIFICATE(buffer, cert_guid);
DBMS_OUTPUT.PUT_LINE('Certificate GUID = ' || cert_guid);
END;
/

Controlliamo le info relative al certificato mediante le viste del dizionario

Creiamo una signature (signature1.dat) utilizzando i byte del nostro record contenuto nella tabella di tipo blockchain

DECLARE
row_data BLOB;
buffer RAW(4000);
inst_id BINARY_INTEGER;
chain_id BINARY_INTEGER;
sequence_no BINARY_INTEGER;
row_len BINARY_INTEGER;
l_file UTL_FILE.FILE_TYPE;
BEGIN
SELECT ORABCTAB_INST_ID$, ORABCTAB_CHAIN_ID$, ORABCTAB_SEQ_NUM$
INTO inst_id, chain_id, sequence_no
FROM BLOCK_CHAIN_TABLE_TEST where order_id=1;
DBMS_BLOCKCHAIN_TABLE.GET_BYTES_FOR_ROW_SIGNATURE ('TEST','BLOCK_CHAIN_TABLE_TEST', inst_id, chain_id, sequence_no, 1, row_data);
row_len := DBMS_LOB.GETLENGTH(row_data);
DBMS_LOB.READ(row_data, row_len, 1, buffer);
l_file := UTL_FILE.fopen('BLOCK','signature1.dat','wb', 32767);
UTL_FILE.put_raw(l_file, buffer, TRUE);
UTL_FILE.fclose(l_file);
END;
/

Creiamo con openssl (dunque fuori al database) la firma ( sign1.final )

openssl dgst -sha512 -sign CAroot.key -out sign1.final signature1.dat

A questo punto possiamo aggiungere la firma alla nostra riga presente nella tabella di blockchain mediante DBMS_BLOCKCHAIN_TABLE.SIGN_ROW

DECLARE
inst_id binary_integer;
chain_id binary_integer;
sequence_no binary_integer;
signature RAW(2000);
cert_guid RAW (16) := HEXTORAW('A2DC03ED3742B210E0532800000ACFB1');
file bfile;
amount number:=2000;
buffer RAW(4000);
BEGIN
SELECT ORABCTAB_INST_ID$, ORABCTAB_CHAIN_ID$, ORABCTAB_SEQ_NUM$
INTO inst_id, chain_id, sequence_no
FROM BLOCK_CHAIN_TABLE_TEST where order_id=1;
file := bfilename('BLOCK', 'sign1.final');
DBMS_LOB.FILEOPEN(file);
dbms_lob.READ(file, amount, 1, signature);
dbms_lob.FILECLOSE(file);
DBMS_BLOCKCHAIN_TABLE.SIGN_ROW('TEST','BLOCK_CHAIN_TABLE_TEST', inst_id, chain_id, sequence_no, NULL, signature, cert_guid, DBMS_BLOCKCHAIN_TABLE.SIGN_ALGO_RSA_SHA2_512);
END;
/

A questo punto possiamo vedere la firma di quel record che certifica il record stesso

select order_id,order_date, order_value,ORABCTAB_SIGNATURE_ALG$, ORABCTAB_SIGNATURE_CERT$,ORABCTAB_SIGNATURE$ from BLOCK_CHAIN_TABLE_TEST where  order_id<3;

Quando utilizzare blockchain table

Di seguito alcuni use-case di quando è utile utilizzare Oracle blockchain table rispetto a Oracle blockchain platform

La features della blockchain table è stata portata anche sulla versione 19c (long term support).

Per i dettagli e altro, mi raccomando andate sempre a leggere la documentazione ufficiale.

Have fun !!!

Ciao

Luca

Disclaimer

The views expressed on this paper are my own and do not necessarily reflect the views of Oracle.

alcune  fonti utili :https://docs.oracle.com/en/database/oracle/oracle-database/20/newft/oracle-blockchain-table.htmlhttps://blogs.oracle.com/blockchain/blockchain-tables-in-oracle-database:-technology-convergencehttps://blogs.oracle.com/blockchain/native-blockchain-tables-extend-oracle-database%e2%80%99s-multi-model-converged-architecturehttps://blogs.oracle.com/coretec/blockchain-inside-oracle-database-20c

--

--