forked from mrsmkl/eth-patricia
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRLPEncode.sol
More file actions
77 lines (71 loc) · 2.53 KB
/
RLPEncode.sol
File metadata and controls
77 lines (71 loc) · 2.53 KB
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
// Library for RLP encoding a list of bytes arrays.
// Modeled after ethereumjs/rlp (https://github.com/ethereumjs/rlp)
// [Very] modified version of Sam Mayo's library.
pragma solidity ^0.4.18;
import "./BytesLib.sol";
library RLPEncode {
// Encode an item (bytes)
function encodeItem(bytes memory self) internal pure returns (bytes) {
bytes memory encoded;
if(self.length == 1 && uint(self[0]) < 0x80) {
encoded = new bytes(1);
encoded = self;
} else {
encoded = BytesLib.concat(encodeLength(self.length, 128), self);
}
return encoded;
}
// Encode a list of items
function encodeList(bytes[] memory self) internal pure returns (bytes) {
bytes memory encoded;
for (uint i=0; i < self.length; i++) {
encoded = BytesLib.concat(encoded, encodeItem(self[i]));
}
return BytesLib.concat(encodeLength(encoded.length, 192), encoded);
}
// Hack to encode nested lists. If you have a list as an item passed here, included
// pass = true in that index. E.g.
// [item, list, item] --> pass = [false, true, false]
function encodeListWithPasses(bytes[] memory self, bool[] pass) internal pure returns (bytes) {
bytes memory encoded;
for (uint i=0; i < self.length; i++) {
if (pass[i] == true) {
encoded = BytesLib.concat(encoded, self[i]);
} else {
encoded = BytesLib.concat(encoded, encodeItem(self[i]));
}
}
return BytesLib.concat(encodeLength(encoded.length, 192), encoded);
}
// Generate the prefix for an item or the entire list based on RLP spec
function encodeLength(uint256 L, uint256 offset) internal pure returns (bytes) {
if (L < 56) {
bytes memory prefix = new bytes(1);
prefix[0] = byte(L + offset);
return prefix;
} else {
// lenLen is the length of the hex representation of the data length
uint lenLen;
uint i = 0x1;
while(L/i != 0) {
lenLen++;
i *= 0x100;
}
bytes memory prefix0 = getLengthBytes(offset + 55 + lenLen);
bytes memory prefix1 = getLengthBytes(L);
return BytesLib.concat(prefix0, prefix1);
}
}
function getLengthBytes(uint256 x) internal pure returns (bytes b) {
// Figure out if we need 1 or two bytes to express the length.
// 1 byte gets us to max 255
// 2 bytes gets us to max 65535 (no payloads will be larger than this)
uint256 nBytes = 1;
if (x > 255) { nBytes = 2; }
b = new bytes(nBytes);
// Encode the length and return it
for (uint i = 0; i < nBytes; i++) {
b[i] = byte(uint8(x / (2**(8*(nBytes - 1 - i)))));
}
}
}