这个对涉及到财产,金融,保险行业来说,这个功能很实用,可以有效保障数据的安全。因为数据一旦被修改,hash值就会变化,整个链就不完整了,就很容易发现问题了。使用区块链表比实现区块链网络或技术更简单,不需要新的硬件设施,该特性是作为Oracle数据库的一部分来交付的。区块链表对应用程序是透明的,开发人员可以使用SQL、PL/SQL、JDBC和其他访问。区块链表还可以参与其他表的事务和查询。
区块链表的使用场景
第一种使用场景
适用于需要存储不变数据的应用程序,例如来自物联网设备的读数、遵从合规性数据等。创建并使用区块链表来直接存储这些数据。
第二种使用场景
现有应用程序需要对常规数据库表的更改进行防篡改审计跟踪。您可以添加一个额外的区块链表,或者更新应用程序,为当前表的每次更新插入一条记录,或者在当前表上创建一个已触发的存储过程,以捕获更新并将更新记录到区块链表中维护的审计跟踪中。
第三种使用场景
使用分布式区块链网络的去集中化应用程序有关。在某些情况下,这些应用程序需要存储大量数据,例如电子健康记录(EHR)、图像、法律协议或合同等。由于分布式网络中节点交换的消息数量非常大,所以大文件或上GB大小的映像文件会造成很高的网络负载。在这种情况下,我们就可以将这些文件或映像文件的hash值存在区块链表中,然后通过这些信息进行交换,进而避免造成网络拥堵,也提高了性能。
创建区块链表
Oracle
20c提供了创建和修改区块链表的DDL和三个有用的PL/SQL包。在该版本中支持的数据类型有NUMBER, VARCHAR2, RAW,
JSON, BLOB, CLOB, DATE;其他的比如LONG, ADTs, TYPE, varray, OBJECTS, ROWID,
BFILE, REF, Collections等暂不支持。
CREATE BLOCKCHAIN TABLE bank_ledger (BANK VARCHAR2(128), DEPOSIT_DATE DATE,DEPOSIT_AMOUNT NUMBER)
NO DROP UNTIL 31 DAYS IDLENO DELETE LOCKED
HASHING USING "sha2_512" VERSION "v1";
注意:区块链表不能在CDB的root下使用,要不会出现下面的提示
ORA-05729: blockchain table cannot be created in root container
NO DROP [UNTIL n DAYS IDLE]
该选项是强制性,它可以防止表被删除,或者在可以删除表之前规定一个不活动的保留期。n的最小值是16,这是一个足够长的周期,可以跨越大多数常见的假期。使用ALTER TABLE子句将保留期限更改为大于16天的新值
NO DELETE [LOCKED] or NO DELETE UNTIL n DAYS AFTER INSERT [LOCKED]
这个是用来控制删除策略,n默认是16。
如果使用了NO DELETE (with or without LOCKED)或NO DELETE UNTIL … LOCKED,这些设置不能修改
如果使用了NO DELETE UNTIL without LOCKED, 有可以通过ALTER TABLE来增加保留的天数,只能增加不能减少
HASHING USING "sha2_512" VERSION "v1"
该选项是强制性,用于指定行链接的哈希计算使用SHA2算法,输出长度为512位
注意:当涉及到ALTER TABLE时,除了上面提到的那些和添加约束时,大多数子句都不允许用于区块链表
区块链表的限制
使用区块链表后,用户不能通过DML更新数据,直接路径写(INSERT AS SELECT, SQL Loader)或通过Golden Gate逻辑复制。除此之外,用户不能做下面的事情:
在设置保留期内删除行,添加/删除/重命名列
删除分区
定义行更新之前触发器
将区块链和非区块链表之间转化
这有助于保护区块链表中的数据免受数据库用户的基本操作和欺诈,包括伪造、重写历史记录等。
区块链表的PL/SQL包
DBMS_BLOCKCHAIN_TABLE
delete_rows() – deletes rows outside retention window (to be renamed to delete_expired_rows() in a future release)
verify_rows() – verifies integrity of the chains
sign_row() – stores user signature for a previously inserted row
get_bytes_for_row_hash() – returns row content data format to compute rows SHA2-512 hash
get_bytes_for_row_signature() – returns the row hash
DBMS_TABLE_DATA
get_bytes_for_column() – returns {column-byte-value} for specified column
get_bytes_for_columns() – returns {column-byte-value}* array for specified columns
get_bytes_for_row() – returns {column-byte-value}* array for all columns of the row
DBMS_USER_CERTS
add_certificate() – inserts cert into “sys.user_certs$” dictionary table, returns a unique GUID
drop_certificate() – deletes the specified cert, if it exists, from “sys.user_certs$” table
区块链表相关的视图
ALL_BLOCKCHAIN_TABLES
DBA_BLOCKCHAIN_TABLES
USER_BLOCKCHAIN_TABLES
CDB_BLOCKCHAIN_TABLES
DBA_CERTIFICATES
USER_CERTIFICATES
CDB_CERTIFICATES
SQL> desc DBA_BLOCKCHAIN_TABLES Name Null? Type ----------------------------------------- -------- ---------------------------- SCHEMA_NAME NOT NULL VARCHAR2(128) TABLE_NAME NOT NULL VARCHAR2(128) ROW_RETENTION NUMBER ROW_RETENTION_LOCKED VARCHAR2(3) TABLE_INACTIVITY_RETENTION NUMBER HASH_ALGORITHM VARCHAR2(8) SQL> SQL> desc DBA_CERTIFICATES Name Null? Type ----------------------------------------- -------- ---------------------------- CERTIFICATE_GUID RAW(16) USER_NAME NOT NULL VARCHAR2(128) DISTINGUISHED_NAME VARCHAR2(2000) CERTIFICATE BLOB SQL>测试区块链表
下面我们通过10046跟踪一下,区块链表的插入,后台到底做了什么事情
SQL> oradebug setmypid
Statement processed.
SQL> oradebug event 10046 trace name context forever,level 12;
Statement processed.
SQL> insert into bank_ledger values('Bank of American',sysdate,100);
1 row created.
SQL> commit;
Commit complete.
SQL> oradebug tracefile_name;
SQL> oradebug event 10046 trace name context off;
SQL> exit
从trace文件中,我们能看到下面的语句,后面带$符号的全是隐藏的列。关于隐藏的列,请参考官方文档https://docs.oracle.com/en/database/oracle/oracle-database/20/admin/managing-tables.html#GUID-02BD6C35-E1E9-41B7-BD56-68C7A667B51F
SELECT "BANK", "DEPOSIT_DATE", "DEPOSIT_AMOUNT", "ORABCTAB_INST_ID$", "ORABCTAB_CHAIN_ID$", "ORABCTAB_SEQ_NUM$", "ORABCTAB_CREATION_TIME$", "ORABCTAB_USER_NUMBER$", "ORABCTAB_HASH$", "ORABCTAB_SIGNATURE$", "ORABCTAB_SIGNATURE_ALG$", "ORABCTAB_SIGNATURE_CERT$" from "SYS"."BANK_LEDGER";
其中hash值是写入隐藏字段orabctab_hash$
然后会更新sys.blockchain_table_chain$表
update sys.blockchain_table_chain$ set hashval_position =:1, max_seq_number =:2 where obj#=:3 and inst_id = :4 and chain_id = :5
SQL> desc sys.blockchain_table_chain$ Name Null? Type ----------------------------------------- -------- ---------------------------- OBJ# NOT NULL NUMBER INST_ID NOT NULL NUMBER CHAIN_ID NOT NULL NUMBER EPOCH# NUMBER HASHVAL_POSITION RAW(2000) MIN_SEQ_NUMBER NUMBER MAX_SEQ_NUMBER NUMBER SPARE1 NUMBER SPARE2 NUMBER SPARE3 NUMBER SPARE4 NUMBER SQL>
下面我们尝试删除更新、drop、truncate、delete操作
Reference
https://blogs.oracle.com/blockchain/native-blockchain-tables-extend-oracle-database%e2%80%99s-multi-model-converged-architecture
https://docs.oracle.com/en/database/oracle/oracle-database/20/admin/managing-tables.html#GUID-43470B0C-DE4A-4640-9278-B066901C3926
https://docs.oracle.com/en/database/oracle/oracle-database/20/newft/oracle-blockchain-table.html
https://blogs.oracle.com/blockchain/oracle-blockchain
https://blogs.oracle.com/blockchain/blockchain-tables-in-oracle-database%3a-technology-convergence