forked from svanas/delphereum
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathweb3.rlp.pas
107 lines (92 loc) · 2.52 KB
/
web3.rlp.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
{******************************************************************************}
{ }
{ Delphereum }
{ }
{ Copyright(c) 2018 Stefan van As <[email protected]> }
{ Github Repository <https://github.com/svanas/delphereum> }
{ }
{ Distributed under Creative Commons NonCommercial (aka CC BY-NC) license. }
{ }
{******************************************************************************}
unit web3.rlp;
{$I web3.inc}
interface
uses
// Delphi
System.Math,
System.SysUtils,
// web3
web3,
web3.utils;
function encode(item: Integer): TBytes; overload;
function encode(const item: string): TBytes; overload;
function encode(item: TVarRec): TBytes; overload;
function encode(items: array of const): TBytes; overload;
implementation
function encodeLength(len, offset: Integer): TBytes;
function toBinary(x: Integer): TBytes;
var
i, r: Word;
begin
if x = 0 then
Result := []
else
begin
DivMod(x, 256, i, r);
Result := toBinary(i) + [r];
end;
end;
var
bin: TBytes;
begin
if len < 56 then
Result := [len + offset]
else
if len < Power(256, 8) then
begin
bin := toBinary(len);
Result := [Length(bin) + offset + 55] + bin;
end
else
raise EWeb3.Create('RLP input is too long.');
end;
function encodeItem(const item: TBytes): TBytes;
var
len: Integer;
begin
len := Length(item);
if (len = 1) and (item[0] < $80) then
Result := item
else
Result := encodeLength(len, $80) + item;
end;
function encode(item: Integer): TBytes;
var
arg: TVarRec;
begin
arg.VType := vtInteger;
arg.VInteger := item;
Result := encode(arg);
end;
function encode(const item: string): TBytes;
var
arg: TVarRec;
begin
arg.VType := vtUnicodeString;
arg.VUnicodeString := Pointer(item);
Result := encode(arg);
end;
function encode(item: TVarRec): TBytes;
begin
Result := encodeItem(web3.utils.fromHex(web3.utils.toHex(item)));
end;
function encode(items: array of const): TBytes;
var
item: TVarRec;
begin
Result := [];
for item in items do
Result := Result + encode(item);
Result := encodeLength(Length(Result), $c0) + Result;
end;
end.