@@ -5,18 +5,18 @@ lang: ja
5
5
sidebarDepth : 2
6
6
---
7
7
8
- 再帰的な長さのプレフィックス(RLP)シリアライゼーションは、イーサリアムの実行クライアントで広く使われています。 RLP はスペース効率に優れたフォーマットで 、ノード間のデータ転送を標準化します。 RLP の目的は 、任意のネストされたバイナリデータの配列をエンコード(符号化)することです。また、RLP はイーサリアムの実行レイヤーのオブジェクトのシリアライズに用いられる主要なエンコーディング方式です。 RLP の唯一の目的は 、構造をエンコードすることです。特定のデータ型(例: 文字列型、浮動小数点型など)のエンコーディングは、上位のプロトコルが行いますが、正の RLP 整数は 、先頭にゼロのないビッグエンディアン・バイナリ形式で表されます(そのため、整数値ゼロは空のバイト配列となります) 。 先頭がゼロのデシリアル化された正の整数は、無効として扱われます。 文字列長の整数表現は、ペイロード内の整数と同様にこの方法でエンコードする必要があります。
8
+ 再帰的な長さのプレフィックス(RLP)シリアライゼーションは、イーサリアムの実行クライアントで広く使われています。 RLPはスペース効率に優れたフォーマットで 、ノード間のデータ転送を標準化します。 RLPの目的は 、任意のネストされたバイナリデータの配列をエンコード(符号化)することです。また、RLPはイーサリアムの実行レイヤーのオブジェクトのシリアライズに用いられる主要なエンコーディング方式です。 RLPの唯一の目的は 、構造をエンコードすることです。特定のデータ型(例: 文字列型、浮動小数点型など)のエンコーディングは、上位のプロトコルが行いますが、正のRLP整数は 、先頭にゼロのないビッグエンディアン・バイナリ形式で表されます(そのため、整数値ゼロは空のバイト配列となります) 。 先頭がゼロのデシリアル化された正の整数は、無効として扱われます。 文字列長の整数表現は、ペイロード内の整数と同様にこの方法でエンコードする必要があります。
9
9
10
- 詳細については、[ イーサリアムイエローペーパー (付録 B )] ( https://ethereum.github.io/yellowpaper/paper.pdf#page=19 ) を参照してください。
10
+ 詳細については、[ イーサリアムイエローペーパー (付録B )] ( https://ethereum.github.io/yellowpaper/paper.pdf#page=19 ) を参照してください。
11
11
12
- RLP を使用して辞書をエンコードするのに、次の 2 つの正規の方法があります 。
12
+ RLPを使用して辞書をエンコードするのに、次の2つの正規の方法があります 。
13
13
14
14
- ` [[k1,v1],[k2,v2]...] ` のように辞書順にキーを並べて使用する
15
15
- イーサリアムのように上位レベルのパトリシア・ツリー・エンコーディングを使用する
16
16
17
17
## 定義 {#definition}
18
18
19
- RLP エンコーディング関数は 、アイテムを取ります。 アイテムは次のように定義されます。
19
+ RLPエンコーディング関数は 、アイテムを取ります。 アイテムは次のように定義されます。
20
20
21
21
- 文字列型(すなわちバイト配列) はアイテム
22
22
- アイテムのリストはアイテム
@@ -30,58 +30,58 @@ RLP エンコーディング関数は、アイテムを取ります。 アイテ
30
30
31
31
本ページのこれ以降では、「文字列」は「あるバイト数のバイナリデータ」を意味することに注意してください。特別なエンコーディングは使用されておらず、文字列が何を指すのかの知識は必要ありません。
32
32
33
- RLP エンコーディングは以下のように定義されます 。
33
+ RLPエンコーディングは以下のように定義されます 。
34
34
35
- - ` [0x00, 0x7f] ` (10 進数 ` [0, 127] ` )の範囲にある 1 バイトは、そのバイト自体が RLP エンコーディングとなる 。
36
- - その他、文字列が 0 ~ 55 バイトの場合、RLP エンコーディングは値が ** 0x80** (10 進数 128 )に、文字列の長さを足した 1 バイト 、続いて文字列で構成される。 したがって、最初の 1 バイトの範囲は ` [0x80, 0xb7] ` (10 進数 ` [128, 183] ` )となる。
37
- - 文字列の長さが 55 バイトを超える場合、RLP エンコーディングは 、** 0xb7** (10 進数 183)にバイナリ形式の文字列長をバイト数を加えた 1 バイト 、続けて文字列の長さ、次に文字列で構成される。 例えば、1024 バイトの長さの文字列は 、` \xb9\x04\x00 ` (10 進数 ` 185, 4, 0 ` )にエンコードされ、その後文字列となる。 ここでは、最初の 1 バイトとして ` 0xb9 ` (183 + 2 = 185)、次に実際の文字列の長さを示す 2 バイトの ` 0x0400 ` (10 進数 1024 )が続く。 したがって、最初の 1 バイトの範囲は 、` [0xb8, 0xbf] ` (10 進数 ` [184, 191] ` )となる。
38
- - リストの全ペイロード(RLP エンコードされるすべてのアイテムを合わせた長さ)が、0 ~ 55 バイトである場合、RLP エンコーディングは 、** 0xc0** にリストの長さを加えた 1 バイト、続けてアイテムを RLP エンコーディングして続けたもので構成される 。 したがって、最初のバイトの範囲は` [0xc0, 0xf7] ` (10 進数 ` [192, 247] ` )となる。
39
- - リストの全ペイロードが、55 バイトを超える場合、RLP エンコーディングは 、** 0xf7** にバイナリ形式のペイロードの長さのバイト数を加えた 1 バイト 、次にペイロードの長さ、アイテムの RLP エンコーディングしたものを続けたもので構成される 。 したがって、最初のバイトの範囲は、` [0xf8, 0xff] ` (10 進数 ` [248, 255] ` )となる 。
35
+ - ` [0x00, 0x7f] ` (10進数 ` [0, 127] ` )の範囲にある1バイトは、そのバイト自体がRLPエンコーディングとなる 。
36
+ - その他、文字列が0~55バイトの場合、RLPエンコーディングは値が ** 0x80** (10進数128 )に、文字列の長さを足した1バイト 、続いて文字列で構成される。 したがって、最初の1バイトの範囲は ` [0x80, 0xb7] ` (10進数 ` [128, 183] ` )となる。
37
+ - 文字列の長さが55バイトを超える場合、RLPエンコーディングは 、** 0xb7** (10進数 183)にバイナリ形式の文字列長をバイト数を加えた1バイト 、続けて文字列の長さ、次に文字列で構成される。 例えば、1024バイトの長さの文字列は 、` \xb9\x04\x00 ` (10進数 ` 185, 4, 0 ` )にエンコードされ、その後文字列となる。 ここでは、最初の1バイトとして ` 0xb9 ` (183 + 2 = 185)、次に実際の文字列の長さを示す2バイトの ` 0x0400 ` (10進数1024 )が続く。 したがって、最初の1バイトの範囲は 、` [0xb8, 0xbf] ` (10進数 ` [184, 191] ` )となる。
38
+ - リストの全ペイロード(例えば、RLPエンコードされるすべてのアイテムを合わせた長さ)が0~55バイトである場合、RLPエンコーディングは 、** 0xc0** にペイロードの長さを加えた1バイト、続けてアイテムをRLPエンコーディングして続けたもので構成される 。 したがって、最初のバイトの範囲は` [0xc0, 0xf7] ` (10進数 ` [192, 247] ` )となる。
39
+ - リストの全ペイロードが、55バイトを超える場合、RLPエンコーディングは 、** 0xf7** にバイナリ形式のペイロードの長さのバイト数を加えた1バイト 、次にペイロードの長さ、アイテムのRLPエンコーディングしたものを続けたもので構成される 。 したがって、最初のバイトの範囲は、` [0xf8, 0xff] ` (10進数 ` [248, 255] ` )となる 。
40
40
41
41
コードでは、これは次のようになります。
42
42
43
43
``` python
44
44
def rlp_encode (input ):
45
45
if isinstance (input ,str ):
46
- if len (input ) == 1 and ord (input ) < 0x 80 : return input
47
- else : return encode_length(len (input ), 0x 80 ) + input
48
- elif isinstance (input ,list ):
46
+ if len (input ) == 1 and ord (input ) < 0x 80 :
47
+ return input
48
+ return encode_length(len (input ), 0x 80 ) + input
49
+ elif isinstance (input , list ):
49
50
output = ' '
50
- for item in input : output += rlp_encode(item)
51
+ for item in input :
52
+ output += rlp_encode(item)
51
53
return encode_length(len (output), 0x c0 ) + output
52
54
53
- def encode_length (L ,offset ):
55
+ def encode_length (L , offset ):
54
56
if L < 56 :
55
57
return chr (L + offset)
56
58
elif L < 256 ** 8 :
57
59
BL = to_binary(L)
58
60
return chr (len (BL ) + offset + 55 ) + BL
59
- else :
60
- raise Exception (" input too long" )
61
+ raise Exception (" input too long" )
61
62
62
63
def to_binary (x ):
63
64
if x == 0 :
64
65
return ' '
65
- else :
66
- return to_binary(int (x / 256 )) + chr (x % 256 )
66
+ return to_binary(int (x / 256 )) + chr (x % 256 )
67
67
```
68
68
69
69
## いくつかの例 {#examples}
70
70
71
71
- 文字列「dog」= [ 0x83, 'd', 'o', 'g' ]
72
- - リスト [ "cat", "dog" ] = ` [ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ] `
72
+ - リスト [ "cat", "dog" ] = ` [ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ] `
73
73
- 空文字列 ('null') = ` [ 0x80 ] `
74
74
- 空リスト = ` [ 0xc0 ] `
75
- - 整数 0 = ` [ 0x80 ] `
76
- - 整数 0 ('\\ x00')のエンコード = ` [ 0x00 ] `
77
- - 整数 15 ('\\ x0f')エンコード = ` [ 0x0f ] `
78
- - 整数 1024 ('\\ x04\\ x00')のエンコード = ` [ 0x82, 0x04, 0x00 ] `
79
- - 3 の [ 集合論的表現] ( http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers ) ` [ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ] `
75
+ - 整数0 = ` [ 0x80 ] `
76
+ - 整数0 ('\\ x00')のエンコード = ` [ 0x00 ] `
77
+ - 整数15 ('\\ x0f')エンコード = ` [ 0x0f ] `
78
+ - 整数1024 ('\\ x04\\ x00')のエンコード = ` [ 0x82, 0x04, 0x00 ] `
79
+ - 3の [ 集合論的表現] ( http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers ) ` [ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ] `
80
80
- 文字列「Lorem ipsum dolor sit amet, consectetur adipisicing elit」= ` [ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ] `
81
81
82
- ## RLP デコードディング {#rlp-decoding}
82
+ ## RLPデコーディング {#rlp-decoding}
83
83
84
- RLP エンコーディング規則とプロセスに従って、RLP デコードの入力は 、バイナリデータ配列とみなされます。 RLP のデコーディングプロセスは 、次のようになります。
84
+ RLPエンコーディング規則とプロセスに従って、RLPデコードの入力は 、バイナリデータ配列とみなされます。 RLPのデコーディングプロセスは 、次のようになります。
85
85
86
86
1 . 入力データの最初のバイト(プレフィックス) とデコーディングするデータ型に従った実際のデータ長とオフセット
87
87
@@ -91,15 +91,15 @@ RLP エンコーディング規則とプロセスに従って、RLP デコード
91
91
92
92
その中で、データ型とオフセットのデコード規則は次のようになります。
93
93
94
- 1 . 最初の 1 バイト (プレフィックス)の範囲が [ 0x00, 0x7f] の場合は、データは文字列型で、文字列はそのバイトそのもの。
94
+ 1 . 最初の1バイト (プレフィックス)の範囲が [ 0x00, 0x7f] の場合は、データは文字列型で、文字列はそのバイトそのもの。
95
95
96
- 2 . 最初の 1 バイトの範囲が [ 0x80, 0xb7] の場合、データは文字列型。最初の 1 バイト、続いて最初の 1 バイトから 0x80 を引いた長さの文字列となる。
96
+ 2 . 最初の1バイトの範囲が [ 0x80, 0xb7] の場合、データは文字列型。最初の1バイト、続いて最初の1バイトから 0x80 を引いた長さの文字列となる。
97
97
98
- 3 . 最初の 1 バイトの範囲が [ 0xb8, 0xbf] の場合は、データは文字列型。最初の 1 バイト、続いて最初の 1 バイトから 0xb7 を引いた文字列長 (バイトで表す)、最後に文字列となる。
98
+ 3 . 最初の1バイトの範囲が [ 0xb8, 0xbf] の場合は、データは文字列型。最初の1バイト、続いて最初の1バイトから0xb7を引いた文字列長 (バイトで表す)、最後に文字列となる。
99
99
100
- 4 . 最初の 1 バイトの範囲が [ 0xc0, 0xf7] の場合は、データはリスト型。最初の 1 バイト、続いて全ペイロードが最初のバイトから 0xc0 を引いたものに等しい、リストの全アイテムを RLP エンコーディングして続けたものとなる 。
100
+ 4 . 最初の1バイトの範囲が [ 0xc0, 0xf7] の場合は、データはリスト型。最初の1バイト、続いて全ペイロードが最初のバイトから0xc0を引いたものに等しい、リストの全アイテムをRLPエンコーディングして続けたものとなる 。
101
101
102
- 5 . 最初の 1 バイトの範囲が [ 0xf8, 0xff] の場合は、データはリスト型。最初の 1 バイト、続いてリストの長さが最初の 1 バイトから 0xf7 を引いたリストの全ペイロード、最後にリストのすべてのアイテムを RLP エンコーディングして続けたものとなる 。
102
+ 5 . 最初の1バイトの範囲が [ 0xf8, 0xff] の場合は、データはリスト型。最初の1バイト、続いてリストの長さが最初の1バイトから0xf7を引いたリストの全ペイロード、最後にリストのすべてのアイテムをRLPエンコーディングして続けたものとなる 。
103
103
104
104
コードでは、これは次のようになります。
105
105
@@ -113,7 +113,7 @@ def rlp_decode(input):
113
113
output = instantiate_str(substr(input , offset, dataLen))
114
114
elif type is list :
115
115
output = instantiate_list(substr(input , offset, dataLen))
116
- output + rlp_decode(substr(input , offset + dataLen))
116
+ output += rlp_decode(substr(input , offset + dataLen))
117
117
return output
118
118
119
119
def decode_length (input ):
@@ -137,24 +137,22 @@ def decode_length(input):
137
137
lenOfListLen = prefix - 0x f7
138
138
listLen = to_integer(substr(input , 1 , lenOfListLen))
139
139
return (1 + lenOfListLen, listLen, list )
140
- else :
141
- raise Exception (" input does not conform to RLP encoding form" )
140
+ raise Exception (" input does not conform to RLP encoding form" )
142
141
143
142
def to_integer (b ):
144
143
length = len (b)
145
144
if length == 0 :
146
145
raise Exception (" input is null" )
147
146
elif length == 1 :
148
147
return ord (b[0 ])
149
- else :
150
- return ord (substr(b, - 1 )) + to_integer(substr(b, 0 , - 1 )) * 256
148
+ return ord (substr(b, - 1 )) + to_integer(substr(b, 0 , - 1 )) * 256
151
149
```
152
150
153
151
## 参考文献 {#further-reading}
154
152
155
- - [ イーサリアムの RLP ] ( https://medium.com/coinmonks/data-structure-in-ethereum-episode-1-recursive-length-prefix-rlp-encoding-decoding-d1016832f919 )
153
+ - [ イーサリアムのRLP ] ( https://medium.com/coinmonks/data-structure-in-ethereum-episode-1-recursive-length-prefix-rlp-encoding-decoding-d1016832f919 )
156
154
- [ イーサリアムの内部: RLP] ( https://medium.com/coinmonks/ethereum-under-the-hood-part-3-rlp-decoding-df236dc13e58 )
157
- - [ Coglio, A. (2020). ACL2 のイーサリアムの再帰的な長さのプレフィックス arXiv preprint arXiv:2009.13769.] ( https://arxiv.org/abs/2009.13769 )
155
+ - [ Coglio, A. (2020). ACL2のイーサリアムの再帰的な長さのプレフィックス arXiv preprint arXiv:2009.13769.] ( https://arxiv.org/abs/2009.13769 )
158
156
159
157
## 関連トピック {#related-topics}
160
158
0 commit comments