B ブロックチェーン表参照
行内容を使用して、行のハッシュ値および署名を独立して検証できます。
行内容と列内容のデータ形式を使用して、行のハッシュ値とユーザー署名を検証するプロシージャまたは関数を作成します。
- ブロックチェーン表の列内容
行の列内容は、列メタデータおよび列データで構成されます。 - ブロックチェーン表の行内容
事前定義された形式を使用して、ブロックチェーン表の行の行内容を計算します。 - ブロックチェーン表の署名ダイジェストの形式
署名ダイジェストは、ブロックチェーン表の各チェーンの最後の行に関するメタデータとデータで構成されます。
親トピック: 付録
B.1 ブロックチェーン表の列内容
行の列内容は、列メタデータおよび列データで構成されます。
列内容のデータ形式は、事前定義された形式のバイトのプラットフォームに依存しないシーケンスで、列メタデータおよび列データに基づいています。列コンテンツのデータ形式の計算方法を理解するには、bctab
表の行を検討します。この表には、bank
とamount
の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バイトの値です
ub2
、ub4
および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
は、便利なユーティリティ・プロシージャです。数値をリトル・エンディアン形式のub2
、ub4
または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 ブロックチェーン表の行内容
事前定義された形式を使用して、ブロックチェーン表の行の行内容を計算します。
行の行内容は、行データとチェーン内の前の行のハッシュ値に基づく、バイトの連続したシーケンスです。行内容のデータ形式は、バイトの順序とシーケンスを定義します。
ハッシュ値を計算するときと、行の署名を計算するときでは、行内容のデータ形式が異なります。
ハッシュ値を計算するときの行内容のデータ形式
ハッシュ値の行内容のデータ形式は、ユーザー列、一部の非表示列、およびチェーン内の前の行のハッシュ値に基づいて計算されます。
ハッシュ値を計算するときに行内容のデータ形式を理解するには、bank
とamount
という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_COLS
のINTERNAL_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進ゼロを追加することによって行われます。
親トピック: ブロックチェーン表参照