日本語PDF

B ブロックチェーン表参照

行内容を使用して、行のハッシュ値および署名を独立して検証できます。

行内容と列内容のデータ形式を使用して、行のハッシュ値とユーザー署名を検証するプロシージャまたは関数を作成します。

B.1 ブロックチェーン表の列内容

行の列内容は、列メタデータおよび列データで構成されます。

列内容のデータ形式は、事前定義された形式のバイトのプラットフォームに依存しないシーケンスで、列メタデータおよび列データに基づいています。列コンテンツのデータ形式の計算方法を理解するには、bctab表の行を検討します。この表には、bankamountの2つの列があります。この表の行には値「Chase」と1000がそれぞれ含まれます。

列データのデータ形式

データ形式は、ユーザー定義列と非表示列の両方について計算されます。列データはプラットフォームに依存せず、SQL DUMP関数を使用して取得できます。

次の例では、データベース文字セットがANSI ASCIIであると仮定し、列データのデータ形式を取得します。

SELECT REGEXP_REPLACE(REGEXP_SUBSTR(DUMP(bank_name, 16), '[^ ]+',1, 3), ',', '') "Data Value" 
    FROM examples.bank_ledger WHERE bank_name = 'MyBank';

Data Value
--------------------------------------------------------------------------------
4368617365

列メタデータのデータ形式

列メタデータは、次の形式の20バイトの構造です。

typedef struct col_meta_data 
{
     ub2  version;                 /* VALUE IS ALWAYS 1/
     ub2  col_position;
     ub2  col_type;
     ub1  is_col_null;
     ub1  reserved1;               /*VALUE IS ALWAYS 0*/
     ub8  col_len;
     ub4  spare;
} col_meta_data;

ここで:

  • ub1は、符号なしのシングルバイト値です
  • ub2は、符号なしshort型で2バイトの値です
  • ub4は、符号なしlong型で4バイトの値です
  • ub8は、符号なしlong long型で8バイトの値です

ub2ub4およびub8は、リトル・エンディアン形式を使用します。

col_meta_data構造の属性では、表内の位置、データ型、列値がNULLかどうか、および列データの長さ(バイト)など、列に関する情報を記述します。

この例では、ASCIIの「Chase」値の列メタデータを、前述の構造を使用して表します。

01 00 
01 00 
01 00 
00 
00
05 00 00 00 00 00 00 00 
00 00 00 00 

最初の行01 00は、データ形式バージョンの2バイト表現です(このリリースでは1)。2行目の01 00は、BANK_NAMEの列位置の2バイト表現(1)です。3行目の01 00は、BANK_NAME列のデータ型の内部コードの2バイト表現です。データ型はVARCHAR2、内部コードは1です。4行目の00には、列の値がNULL (01)かNULLでない(00)かを指定するバイトがあります。列値は「Chase」です。そのためNULLではありません。5行目の00は予約済バイトであり、このリリースではゼロである必要があります。6行目は05 00 00 00 00 00 00 00です。8バイトの長さです。値「Chase」はデータベース文字セットで5バイトです。7行目の00 00 00 00は4つの予約済バイトであり、このリリースでは、それぞれがゼロである必要があります。

列値「Chase」の列内容のデータ書式は、その列メタデータおよび列データからのバイトを連結したものです。したがって、列内容のデータ形式は次の値になります。

01 00 
01 00 
01 00 
00 
00
05 00 00 00 00 00 00 00 
00 00 00 00 
43 68 61 73 65

例B-1 列メタデータ値を構成するためのユーザー定義ファンクションの作成

プロシージャlittle_endian_ubxは、便利なユーティリティ・プロシージャです。数値をリトル・エンディアン形式のub2ub4またはub8値に変換します。パラメータxは、列のデータ型を表します。ub2入力には値2を、ub4入力には4を、ub8入力には8を使用します。

CREATE OR REPLACE FUNCTION little_endian_ubx(value IN NUMBER, x IN NUMBER) RETURN RAW IS
  format VARCHAR2(16);
  string VARCHAR2(16);
  result RAW(8);
BEGIN
  format := RPAD('0', 2*x-1, '0') || 'X';       -- conversion format is all zeroes and a final X
  string := SUBSTR(TO_CHAR(value, format), 2);  -- use SUBSTR to strip leading space
  dbms_output.put_line('string is ' || string);
  result := utl_raw.reverse(HEXTORAW(string));
  dbms_output.put_line('result is ' || RAWTOHEX(result));
  RETURN result;
END little_endian_ubx;

B.2 ブロックチェーン表の行内容

事前定義された形式を使用して、ブロックチェーン表の行の行内容を計算します。

行の行内容は、行データとチェーン内の前の行のハッシュ値に基づく、バイトの連続したシーケンスです。行内容のデータ形式は、バイトの順序とシーケンスを定義します。

ハッシュ値を計算するときと、行の署名を計算するときでは、行内容のデータ形式が異なります。

ハッシュ値を計算するときの行内容のデータ形式

ハッシュ値の行内容のデータ形式は、ユーザー列、一部の非表示列、およびチェーン内の前の行のハッシュ値に基づいて計算されます。

ハッシュ値を計算するときに行内容のデータ形式を理解するには、bankamountという2列を含むブロックチェーン表bctabを考えます。この表の2行目には値「Chase」と1000がそれぞれ含まれます。行のハッシュ値を計算する際、行内容のデータ形式は、次に示すバイト値をこの順序で連結することで取得されます。

  • 「Chase」値が含まれるbank列のデータ形式
  • 値1000が含まれるamount列のデータ形式
  • 非表示列ORABCTAB_INST_ID$のデータ形式
  • 非表示列ORABCTAB_CHAIN_ID$のデータ形式
  • 非表示列ORABCTAB_SEQ_NUM$のデータ形式
  • 非表示列ORABCTAB_CREATION_TIME$のデータ形式
  • 非表示列ORABCTAB_USER_NUMBER$のデータ形式
  • 表の最初の行のハッシュ値のデータ形式(両方の行が同じチェーンにあると仮定した場合)

列の順序は、ビューALL_TAB_COLSINTERNAL_COLUMN_ID列によって決定されます。

行の署名を計算するときの行内容のデータ形式

行署名の行内容のデータ形式は、行のハッシュ値に基づいて計算されます。

B.3 ブロックチェーン表の署名ダイジェストの形式

署名ダイジェストは、ブロックチェーン表の各チェーンの最後の行に関するメタデータとデータで構成されます。

署名ダイジェストのデータ形式には、ヘッダーと行情報の配列が含まれます。

ヘッダーの構造は、次のとおりです。

{
    ub1    version; 
                 /* 1 in 19.x */
    ub1    reserved_1;
    ub1    reserved_2;
    ub1    reserved_3;
    ub4    reserved_4;
    ub8    total_length;
                 /* total length of signature content buffer, except version, reserved_% and total_length fields */
    ub1    pdb_guid[16];
                 /* 16 bytes long PDB GUID */
    ub4    owner_schema_objn;
    ub4    blockchain_table_objn;
    ub4    signature_algorithm;
    ub4    number_of_rows;
 }

行情報の構造は、次のとおりです。

{
    ub4   instance_id ;
    ub4   chain_id
    ub8   sequence_number;
    ub4   user_number;
    ub1   row_creation_time[16];
                /* UTC format that Oracle uses has 13 bytes; padded 3 bytes */
    ub4   crypto_hash_len;
    ub1  *crypto_hash;
                /* padded to 4 byte boundary */
    ub4   user_columns_count;
                /* always 0 in 19.x
                 * padded to 8 byte boundary */
    ub8   user_columns_data_len;
                /* always 0 in 19.x */
}

ここで:

  • ub1は、符号なしのシングルバイト値です
  • ub4は、符号なしlong型で4バイトの値です
  • ub8は、符号なしlong型で8バイトの値です

ub4およびub8は、リトル・エンディアン形式を使用します。

パディングは、2進ゼロを追加することによって行われます。