Oracle Livelabs Lab: Database 21c - Blockchain Workshop

This lab is based on the Database 21c - Blockchain Workshop lab guide in Oracle Livalabs . It takes about 1 hour.

concept

Blockchain tables are append-only tables that only allow insert operations. Suppress or limit deletion of rows based on time. Rows in the blockchain table are tamper-proof through special sorting and linking algorithms. Users can verify that rows have not been tampered with. Hash values ​​that are part of the row metadata are used to link and validate rows.

Blockchain tables enable you to implement a centralized ledger model where all participants in the blockchain network have access to the same tamper-proof ledger.

The centralized ledger model reduces the administrative overhead of building a decentralized ledger network , has relatively low latency compared to decentralized ledgers , increases developer productivity, reduces time-to-market, and saves organizations significant amounts of money. Database users can continue to use the same tools and practices they use for other database application development.

experiment procedure

This experiment requires an OCI environment and a VM DBCS.
The shape of VM DBCS can use VM Standard2.1, although the original text suggests VM Standard2.4.
But be sure to note that you must use LVM instead of ASM . because:

  1. The LVM environment will automatically create the /u02 and /u03 directories. mkdir -pTherefore, the subsequent script does not specify the option when creating the directory
  2. The database template used for dbca database construction will be deleted when using ASM, but will be retained when using LVM. The purpose is to create only one CDB to run under one tenant.

This is also emphasized in the original text:

Note: This is very important to choose Logical Volume Manager

If dbca is used in the ASM environment, the following error will be reported:

[FATAL] [DBT-10508] Invalid template file specified (/u01/app/oracle/product/21.0.0.0/dbhome_1/assistants/dbca/templates/General_Purpose.dbc).
   CAUSE: Either the given template path is not valid file path or could not locate the given template in the local file system.
   ACTION: Verify the existance of the template file.

Create a directory structure:

sudo mkdir /u02/app/oracle/oradata/CDB21
sudo chown oracle:oinstall /u02/app/oracle/oradata/CDB21
sudo chmod 755 /u02/app/oracle/oradata/CDB21
sudo mkdir /u02/app/oracle/oradata/pdb21
sudo chown oracle:oinstall /u02/app/oracle/oradata/pdb21
sudo chmod 755 /u02/app/oracle/oradata/pdb21
sudo mkdir /u02/app/oracle/oradata/PDB21
sudo chown oracle:oinstall /u02/app/oracle/oradata/PDB21
sudo chmod 755 /u02/app/oracle/oradata/PDB21
sudo mkdir /u02/app/oracle/oradata/toys_root
sudo chown oracle:oinstall /u02/app/oracle/oradata/toys_root
sudo chmod 755 /u02/app/oracle/oradata/toys_root
sudo mkdir /u03/app/oracle/fast_recovery_area
sudo chown oracle:oinstall /u03/app/oracle/fast_recovery_area
sudo chmod 755 /u03/app/oracle/fast_recovery_area

Get the script:

sudo su - oracle
cd /home/oracle
wget https://objectstorage.us-ashburn-1.oraclecloud.com/p/OKr2yAGkytLaadBqjdMiQKkiUjwgoyvyYaB0YVT2AA4G2sZWr3GG_QZRhv_4gYKS/n/c4u04/b/data-management-library-files/o/Cloud_21c_Labs.zip
unzip Cloud_21c_Labs.zip

Run the script to modify the password in all scripts:

$ chmod 777 /home/oracle/labs/update_pass.sh
$ /home/oracle/labs/update_pass.sh
Enter the password you set during the DBSystem creation: WElcome123##

Create a database (before creating a database, it is recommended to shut down the default CDB to free up memory):

cd /home/oracle/labs/M104784GC10
./create_CDB21.sh

Make sure your tnsnames.ora contains the following entries, where CDB21 is automatically generated, and the remaining 2 need to be added manually:

$ cat /u01/app/oracle/homes/OraDB21Home1/network/admin/tnsnames.ora
CDB21 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = blkc.sub07281614200.training.oraclevcn.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = CDB21)
    )
  )

PDB21 =
(DESCRIPTION =
 (ADDRESS = (PROTOCOL = TCP)(HOST = blkc.sub07281614200.training.oraclevcn.com)(PORT = 1521))
 (CONNECT_DATA =
  (SERVER = DEDICATED)
  (SERVICE_NAME = PDB21)
 )
)

PDB21_2 =
(DESCRIPTION =
 (ADDRESS = (PROTOCOL = TCP)(HOST = blkc.sub07281614200.training.oraclevcn.com)(PORT = 1521))
 (CONNECT_DATA =
  (SERVER = DEDICATED)
  (SERVICE_NAME = PDB21_2)
 )
)

Confirm that the database is started and you can log in:

ps -ef|grep smon
ORAENV_ASK=NO
export ORACLE_SID=CDB21
. oraenv
sqlplus sys/WElcome123##@cdb21 AS SYSDBA
sqlplus sys/WElcome123##@pdb21 AS SYSDBA

Confirm that the PDB was created:

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         4 PDB21                          READ WRITE NO

Create HR Schema and auditor users:

cd /home/oracle/labs/M104781GC10
./setup_user.sh

create:

$ sqlplus auditor/WElcome123##@PDB21

-- 以下4个子句都是必须的
CREATE BLOCKCHAIN TABLE ledger_emp (employee_id NUMBER, salary NUMBER)
                        NO DROP UNTIL 31 DAYS IDLE
                        NO DELETE LOCKED
                        HASHING USING "SHA2_512" VERSION "v1";

SELECT row_retention, row_retention_locked,
                        table_inactivity_retention, hash_algorithm  
                  FROM   user_blockchain_tables
                  WHERE  table_name='LEDGER_EMP';

ROW_RETENTION ROW TABLE_INACTIVITY_RETENTION HASH_ALG
------------- --- -------------------------- --------
       365000 YES                         31 SHA2_512

See here for help on ALL_BLOCKCHAIN_TABLES .
ROW_RETENTION means: the minimum number of days that must be retained and cannot be deleted after a row is inserted into the table

ROW_RETENTION_LOCKED indicates whether the row retention period of the blockchain table is locked. Possible values:

  • YES: The row retention period is locked. You cannot change the row retention period
  • NO: The row retention period is not locked. You can change the row retention period to a value higher than the current value using the SQL statement ALTER TABLE … NO DELETE UNTIL n DAYS AFTER INSERT

TABLE_INACTIVITY_RETENTION indicates the number of days that the blockchain table must be inactive before it can be deleted, that is, the number of days that must pass after the last row was inserted before the table can be deleted. Tables with no rows can be dropped at any time, regardless of the column value.

Hidden columns do not appear in the table's description:

SQL> DESC ledger_emp
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 EMPLOYEE_ID                                        NUMBER
 SALARY                                             NUMBER

Show hidden columns:

COL "Data Length" FORMAT 9999
COL "Column Name" FORMAT A24
COL "Data Type" FORMAT A28
SELECT internal_column_id "Col ID", SUBSTR(column_name,1,30) "Column Name",
	SUBSTR(data_type,1,30) "Data Type", data_length "Data Length"
    FROM   user_tab_cols       
    WHERE  table_name = 'LEDGER_EMP' ORDER BY internal_column_id;

    Col ID Column Name              Data Type                    Data Length
---------- ------------------------ ---------------------------- -----------
         1 EMPLOYEE_ID              NUMBER                                22
         2 SALARY                   NUMBER                                22
         3 ORABCTAB_INST_ID$        NUMBER                                22
         4 ORABCTAB_CHAIN_ID$       NUMBER                                22
         5 ORABCTAB_SEQ_NUM$        NUMBER                                22
         6 ORABCTAB_CREATION_TIME$  TIMESTAMP(6) WITH TIME ZONE           13
         7 ORABCTAB_USER_NUMBER$    NUMBER                                22
         8 ORABCTAB_HASH$           RAW                                 2000
         9 ORABCTAB_SIGNATURE$      RAW                                 2000
        10 ORABCTAB_SIGNATURE_ALG$  NUMBER                                22
        11 ORABCTAB_SIGNATURE_CERT$ RAW                                   16
        12 ORABCTAB_SPARE$          RAW                                 2000

12 rows selected.

So far, this table does not have any data.

Insert a row:

INSERT INTO ledger_emp VALUES (106,12000);
commit;

Show the rest of the inner columns of this row:

COL "Chain date" FORMAT A17
COL "Chain ID" FORMAT 99999999
COL "Seq Num" FORMAT 99999999
COL "User Num" FORMAT 9999999
COL "Chain HASH" FORMAT 99999999999999
SELECT ORABCTAB_CHAIN_ID$ "Chain ID", ORABCTAB_SEQ_NUM$ "Seq Num",
                to_char(ORABCTAB_CREATION_TIME$,'dd-Mon-YYYY hh-mi') "Chain date",
                ORABCTAB_USER_NUMBER$ "User Num", ORABCTAB_HASH$ "Chain HASH"
        FROM   ledger_emp;

 Chain ID   Seq Num Chain date        User Num
--------- --------- ----------------- --------
Chain HASH
--------------------------------------------------------------------------------
       23         1 26-Dec-2021 12-06      112
FE6E2F3783A183B314D8798FE0BC2C2396D2998AD3413547B658B7A16B112924E78A0817D15A17DD
7CC79DAA48B22416FD01D2F80269091AE8C9840545AE2343

Insert a row as user hr, and view internal columns as user auditor:

GRANT insert ON ledger_emp TO hr;
CONNECT hr/WElcome123##@PDB21
INSERT INTO  auditor.ledger_emp VALUES (106,24000);
commit;
CONNECT auditor/WElcome123##@PDB21

SELECT ORABCTAB_CHAIN_ID$ "Chain ID", ORABCTAB_SEQ_NUM$ "Seq Num",
                  to_char(ORABCTAB_CREATION_TIME$,'dd-Mon-YYYY hh-mi') "Chain date",
                  ORABCTAB_USER_NUMBER$ "User Num", ORABCTAB_HASH$ "Chain HASH",
                  employee_id, salary
            FROM   ledger_emp;

 Chain ID   Seq Num Chain date        User Num
--------- --------- ----------------- --------
Chain HASH
--------------------------------------------------------------------------------
EMPLOYEE_ID     SALARY
----------- ----------
       23         1 26-Dec-2021 12-06      112
FE6E2F3783A183B314D8798FE0BC2C2396D2998AD3413547B658B7A16B112924E78A0817D15A17DD
7CC79DAA48B22416FD01D2F80269091AE8C9840545AE2343
        106      12000

       23         2 26-Dec-2021 12-11      111
B12760350B7B533050754616B800040ACE673A5B572D233D9F22B4CC8090290E0B5884450B1C4078
1880CE927A41DF2CCBC87886896EA94D890078F67434F6AB
        106      24000

Observe that the User Num is different. This value is the same as the value of the V$SESSION.USER# column.

You cannot delete rows in a blockchain table using the DML DELETE command. You must use the DBMS_BLOCKCHAIN_TABLE package. :

DELETE FROM ledger_emp WHERE ORABCTAB_USER_NUMBER$ = 111;

ORA-05715: operation not allowed on the blockchain or immutable table

The following procedure executes successfully, but no rows are deleted. Because these rows have not passed the retention period:

SET SERVEROUTPUT ON
DECLARE
      NUMBER_ROWS NUMBER;
    BEGIN
      DBMS_BLOCKCHAIN_TABLE.DELETE_EXPIRED_ROWS('AUDITOR','LEDGER_EMP', null, NUMBER_ROWS);
      DBMS_OUTPUT.PUT_LINE('Number of rows deleted=' || NUMBER_ROWS);
    END;
    /

Empty tables are also not allowed:

SQL> TRUNCATE TABLE ledger_emp;
TRUNCATE TABLE ledger_emp
               *
ERROR at line 1:
ORA-05715: operation not allowed on the blockchain or immutable table

Modifying the retention period is also not allowed. Because the table was previously created with the NO DELETE LOCKED attribute. The LOCKED clause indicates that you can never modify the row retention period in the future:

SQL> ALTER TABLE ledger_emp NO DELETE UNTIL 15 DAYS AFTER INSERT;
ALTER TABLE ledger_emp NO DELETE UNTIL 15 DAYS AFTER INSERT
*
ERROR at line 1:
ORA-05741: minimum retention time too low, should be at least 16 days

Dropping table failed because 31 days of inactivity have not elapsed:

SQL> DROP TABLE ledger_emp;
DROP TABLE ledger_emp
           *
ERROR at line 1:
ORA-05723: drop blockchain or immutable table LEDGER_EMP not allowed

Changing the inactivity period to be longer is allowed, but not shorter:

SQL> ALTER TABLE ledger_emp NO DROP UNTIL 1 DAYS IDLE;
ALTER TABLE ledger_emp NO DROP UNTIL 1 DAYS IDLE
*
ERROR at line 1:
ORA-05732: retention value cannot be lowered


SQL> ALTER TABLE ledger_emp NO DROP UNTIL 40 DAYS IDLE;

Table altered.

You can only increase the value for the inactive period. This prohibits the possibility of deleting any historical information that needs to be preserved for security purposes.

Execute the following two SQLs, the first one fails because the retention period is at least 16 days:

CREATE BLOCKCHAIN TABLE auditor.ledger_test (id NUMBER, label VARCHAR2(2))
          NO DROP UNTIL 1 DAYS IDLE
          NO DELETE UNTIL 5 DAYS AFTER INSERT
          HASHING USING "SHA2_512" VERSION "v1";

ERROR at line 1:
ORA-05741: minimum retention time too low, should be at least 16 days

CREATE BLOCKCHAIN TABLE auditor.ledger_test (id NUMBER, label VARCHAR2(2))
          NO DROP UNTIL 16 DAYS IDLE
          NO DELETE UNTIL 16 DAYS AFTER INSERT
          HASHING USING "SHA2_512" VERSION "v1";
		  
Table created.

Insert data as hr user, and then view data as auditor user:

GRANT insert ON auditor.ledger_test TO hr;
CONNECT hr/WElcome123##@PDB21
INSERT INTO auditor.ledger_test VALUES (1,'A1');
COMMIT;
CONNECT auditor/WElcome123##@PDB21

SELECT * FROM auditor.ledger_test;

        ID LA
---------- --
         1 A1

SET SERVEROUTPUT ON
DECLARE
      row_count NUMBER;
      verify_rows NUMBER;
      instance_id NUMBER;
    BEGIN
      FOR instance_id IN 1 .. 2 LOOP
        SELECT COUNT(*) INTO row_count FROM auditor.ledger_test WHERE ORABCTAB_INST_ID$=instance_id;
        DBMS_BLOCKCHAIN_TABLE.VERIFY_ROWS('AUDITOR','LEDGER_TEST', NULL, NULL, instance_id, NULL, verify_rows);
        DBMS_OUTPUT.PUT_LINE('Number of rows verified in instance Id '|| instance_id || ' = '|| row_count);
      END LOOP;
    END;
    /

Number of rows verified in instance Id 1 = 1
Number of rows verified in instance Id 2 = 0

PL/SQL procedure successfully completed.

Guess you like

Origin blog.csdn.net/stevensxiao/article/details/122152519