Nethereum.RLP
5.8.0
Prefix Reserved
dotnet add package Nethereum.RLP --version 5.8.0
NuGet\Install-Package Nethereum.RLP -Version 5.8.0
<PackageReference Include="Nethereum.RLP" Version="5.8.0" />
<PackageVersion Include="Nethereum.RLP" Version="5.8.0" />
<PackageReference Include="Nethereum.RLP" />
paket add Nethereum.RLP --version 5.8.0
#r "nuget: Nethereum.RLP, 5.8.0"
#:package Nethereum.RLP@5.8.0
#addin nuget:?package=Nethereum.RLP&version=5.8.0
#tool nuget:?package=Nethereum.RLP&version=5.8.0
Nethereum.RLP
Recursive Length Prefix (RLP) encoding and decoding for Ethereum data serialization.
Overview
Nethereum.RLP implements Ethereum's primary data serialization format. RLP encodes arbitrarily nested arrays of binary data into a compact byte representation. It is used throughout Ethereum for encoding transactions, blocks, state tries, and network messages.
Key Features
- Encode Elements: Encode single items (bytes, strings, integers) to RLP format
- Encode Lists: Encode collections and nested structures to RLP format
- Decode RLP: Deserialize RLP-encoded data back to elements or collections
- Type Conversions: Extension methods for encoding/decoding int, BigInteger, and string types
- Ethereum Compatibility: Full compliance with Ethereum's RLP specification
Installation
dotnet add package Nethereum.RLP
Dependencies
- Nethereum.Hex - Hexadecimal encoding/decoding
Key Concepts
What is RLP?
RLP (Recursive Length Prefix) is a space-efficient encoding method for arbitrarily nested arrays of binary data. It is the main encoding method used to serialize objects in Ethereum.
Key Principles:
- RLP only encodes structure (nested arrays)
- Atomic data types (integers, strings) are encoded as byte arrays
- Integers are represented in big-endian binary form
- Zero-valued bytes are trimmed from the front of integers
RLP Encoding Rules
Single Bytes (0x00 - 0x7f)
For a single byte whose value is in the [0x00, 0x7f] range, that byte is its own RLP encoding.
// Character 'd' (0x64) encodes as itself
RLP.EncodeElement(new byte[] { 0x64 }); // Result: [0x64]
Short Strings (0-55 bytes)
If a string is 0-55 bytes long, the RLP encoding consists of a single byte with value 0x80 plus the length of the string, followed by the string.
// "dog" = 3 bytes
// Encoded as: 0x83 (0x80 + 3) + "dog" bytes
// Result: 0x83646f67
Long Strings (>55 bytes)
If a string is more than 55 bytes long, the RLP encoding consists of:
- Single byte with value 0xb7 plus the length of the length
- The length of the string
- The string itself
// 56-byte string encodes with 0xb8 prefix
// 0xb8 (0xb7 + 1) + 0x38 (length = 56) + string bytes
Short Lists (0-55 bytes total payload)
Lists with total payload 0-55 bytes use a single byte with value 0xc0 plus the length, followed by concatenated RLP encodings of items.
// ["cat", "dog"]
// Encoded: 0xc8 + RLP("cat") + RLP("dog")
Long Lists (>55 bytes total payload)
Lists with payload >55 bytes use 0xf7 plus length-of-length encoding, similar to long strings.
RLP Elements
- RLPItem: Represents a single encoded value (byte array)
- RLPCollection: Represents a list of RLP elements (can contain RLPItems or nested RLPCollections)
Quick Start
using Nethereum.RLP;
using Nethereum.Hex.HexConvertors.Extensions;
// Encode a string
string text = "dog";
byte[] textBytes = text.ToBytesForRLPEncoding();
byte[] encoded = RLP.EncodeElement(textBytes);
// Result: 0x83646f67
// Encode an integer
int number = 1000;
byte[] numberBytes = number.ToBytesForRLPEncoding();
byte[] encodedNum = RLP.EncodeElement(numberBytes);
// Result: 0x8203e8
// Encode a list
string[] items = { "cat", "dog" };
byte[][] itemBytes = items.ToBytesForRLPEncoding();
byte[][] encodedItems = new byte[itemBytes.Length][];
for (int i = 0; i < itemBytes.Length; i++)
{
encodedItems[i] = RLP.EncodeElement(itemBytes[i]);
}
byte[] encodedList = RLP.EncodeList(encodedItems);
// Result: 0xc88363617483646f67
// Decode RLP
IRLPElement decoded = RLP.Decode(encoded);
string decodedText = decoded.RLPData.ToStringFromRLPDecoded();
// Result: "dog"
Usage Examples
Example 1: Encoding Strings
using Nethereum.RLP;
using Nethereum.Hex.HexConvertors.Extensions;
// Empty string
string empty = "";
byte[] emptyBytes = empty.ToBytesForRLPEncoding();
byte[] encoded = RLP.EncodeElement(emptyBytes);
// Result: 0x80
// Single character
string single = "d";
byte[] singleBytes = single.ToBytesForRLPEncoding();
byte[] encodedSingle = RLP.EncodeElement(singleBytes);
// Result: 0x64 (single byte in range 0x00-0x7f encodes as itself)
// Short string
string dog = "dog";
byte[] dogBytes = dog.ToBytesForRLPEncoding();
byte[] encodedDog = RLP.EncodeElement(dogBytes);
Assert.Equal("83646f67", encodedDog.ToHex());
// Decode back
IRLPElement decoded = RLP.Decode(encodedDog);
string decodedStr = decoded.RLPData.ToStringFromRLPDecoded();
Assert.Equal("dog", decodedStr);
Example 2: Encoding Integers
using Nethereum.RLP;
using Nethereum.Hex.HexConvertors.Extensions;
// Zero encodes as empty byte array
int zero = 0;
byte[] zeroBytes = zero.ToBytesForRLPEncoding();
byte[] encodedZero = RLP.EncodeElement(zeroBytes);
// Result: 0x80 (empty byte array)
// Small integer (< 128)
int small = 15;
byte[] smallBytes = small.ToBytesForRLPEncoding();
byte[] encodedSmall = RLP.EncodeElement(smallBytes);
// Result: 0x0f (single byte in range encodes as itself)
// Medium integer
int medium = 1000;
byte[] mediumBytes = medium.ToBytesForRLPEncoding();
byte[] encodedMedium = RLP.EncodeElement(mediumBytes);
Assert.Equal("8203e8", encodedMedium.ToHex());
// Decode back
IRLPElement decoded = RLP.Decode(encodedMedium);
int decodedInt = decoded.RLPData.ToIntFromRLPDecoded();
Assert.Equal(1000, decodedInt);
Example 3: Encoding BigInteger
using Nethereum.RLP;
using Nethereum.Hex.HexConvertors.Extensions;
using System.Numerics;
// Large BigInteger
byte[] hexBytes = "100102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
.HexToByteArray();
BigInteger bigInt = hexBytes.ToBigIntegerFromRLPDecoded();
byte[] bigIntBytes = bigInt.ToBytesForRLPEncoding();
byte[] encoded = RLP.EncodeElement(bigIntBytes);
Assert.Equal(
"a0100102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
encoded.ToHex()
);
// Decode back
IRLPElement decoded = RLP.Decode(encoded);
BigInteger decodedBigInt = decoded.RLPData.ToBigIntegerFromRLPDecoded();
Assert.Equal(bigInt, decodedBigInt);
Example 4: Encoding Lists
using Nethereum.RLP;
using Nethereum.Hex.HexConvertors.Extensions;
// Empty list
byte[][] emptyList = new byte[0][];
byte[] encodedEmpty = RLP.EncodeList(emptyList);
Assert.Equal("c0", encodedEmpty.ToHex());
RLPCollection decodedEmpty = RLP.Decode(encodedEmpty) as RLPCollection;
Assert.Equal(0, decodedEmpty.Count);
// Short string list
string[] strings = { "cat", "dog" };
byte[][] stringBytes = strings.ToBytesForRLPEncoding();
// Encode each element
byte[][] encodedElements = new byte[stringBytes.Length][];
for (int i = 0; i < stringBytes.Length; i++)
{
encodedElements[i] = RLP.EncodeElement(stringBytes[i]);
}
// Encode the list
byte[] encodedList = RLP.EncodeList(encodedElements);
Assert.Equal("c88363617483646f67", encodedList.ToHex());
// Decode back
RLPCollection decodedList = RLP.Decode(encodedList) as RLPCollection;
Assert.Equal("cat", decodedList[0].RLPData.ToStringFromRLPDecoded());
Assert.Equal("dog", decodedList[1].RLPData.ToStringFromRLPDecoded());
Example 5: Encoding Long Strings
using Nethereum.RLP;
using Nethereum.Hex.HexConvertors.Extensions;
// String longer than 55 bytes
string longString = "Lorem ipsum dolor sit amet, consectetur adipisicing elit"; // 56 bytes
byte[] longBytes = longString.ToBytesForRLPEncoding();
byte[] encoded = RLP.EncodeElement(longBytes);
// Result starts with 0xb8 (0xb7 + 1 for length-of-length)
// followed by 0x38 (length = 56 in hex)
// followed by the string bytes
Assert.Equal(
"b8384c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c6974",
encoded.ToHex()
);
// Decode back
IRLPElement decoded = RLP.Decode(encoded);
string decodedStr = decoded.RLPData.ToStringFromRLPDecoded();
Assert.Equal(longString, decodedStr);
Example 6: Mixed List with Long String
using Nethereum.RLP;
using Nethereum.Hex.HexConvertors.Extensions;
// List containing short and long strings
string short = "cat";
string long = "Lorem ipsum dolor sit amet, consectetur adipisicing elit";
string[] mixed = { short, long };
byte[][] mixedBytes = mixed.ToBytesForRLPEncoding();
// Encode each element
byte[][] encodedElements = new byte[mixedBytes.Length][];
for (int i = 0; i < mixedBytes.Length; i++)
{
encodedElements[i] = RLP.EncodeElement(mixedBytes[i]);
}
// Encode the list
byte[] encodedList = RLP.EncodeList(encodedElements);
Assert.Equal(
"f83e83636174b8384c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c6974",
encodedList.ToHex()
);
// Decode back
RLPCollection decoded = RLP.Decode(encodedList) as RLPCollection;
Assert.Equal("cat", decoded[0].RLPData.ToStringFromRLPDecoded());
Assert.Equal(long, decoded[1].RLPData.ToStringFromRLPDecoded());
Example 7: Multiple String List
using Nethereum.RLP;
using Nethereum.Hex.HexConvertors.Extensions;
// List with three short strings
string[] animals = { "dog", "god", "cat" };
byte[][] animalBytes = animals.ToBytesForRLPEncoding();
byte[][] encodedElements = new byte[animalBytes.Length][];
for (int i = 0; i < animalBytes.Length; i++)
{
encodedElements[i] = RLP.EncodeElement(animalBytes[i]);
}
byte[] encodedList = RLP.EncodeList(encodedElements);
Assert.Equal("cc83646f6783676f6483636174", encodedList.ToHex());
// Decode and verify
RLPCollection decoded = RLP.Decode(encodedList) as RLPCollection;
for (int i = 0; i < animals.Length; i++)
{
Assert.Equal(animals[i], decoded[i].RLPData.ToStringFromRLPDecoded());
}
Example 8: Working with Raw Bytes
using Nethereum.RLP;
using Nethereum.Hex.HexConvertors.Extensions;
// Encode raw byte array
byte[] data = new byte[] { 0x01, 0x02, 0x03, 0x04 };
byte[] encoded = RLP.EncodeElement(data);
// Decode
IRLPElement decoded = RLP.Decode(encoded);
byte[] decodedBytes = decoded.RLPData;
Assert.Equal(data, decodedBytes);
// Empty byte array
byte[] empty = new byte[0];
byte[] encodedEmpty = RLP.EncodeElement(empty);
Assert.Equal("80", encodedEmpty.ToHex());
IRLPElement decodedEmpty = RLP.Decode(encodedEmpty);
Assert.Null(decodedEmpty.RLPData); // Empty encodes/decodes as null
API Reference
RLP Class
Main class for encoding and decoding RLP data.
public class RLP
{
// Constants
public const byte OFFSET_SHORT_LIST = 0xc0;
public static readonly byte[] EMPTY_BYTE_ARRAY = new byte[0];
public static readonly byte[] ZERO_BYTE_ARRAY = { 0 };
// Encoding
public static byte[] EncodeElement(byte[] srcData);
public static byte[] EncodeList(params byte[][] elements);
// Decoding
public static IRLPElement Decode(byte[] data);
public static IRLPElement Decode(byte[] data, int position);
// Utilities
public static int ByteArrayToInt(byte[] bytes);
public static byte[] IntToByteArray(int value);
}
IRLPElement Interface
Base interface for RLP elements.
public interface IRLPElement
{
byte[] RLPData { get; }
}
RLPItem Class
Represents a single RLP-encoded value.
public class RLPItem : IRLPElement
{
public byte[] RLPData { get; }
}
RLPCollection Class
Represents a list of RLP elements (can be nested).
public class RLPCollection : List<IRLPElement>, IRLPElement
{
public byte[] RLPData { get; }
// List operations via base class
public int Count { get; }
public IRLPElement this[int index] { get; }
}
Conversion Extension Methods
Extensions for converting types to/from RLP encoding.
public static class ConvertorForRLPEncodingExtensions
{
// Encoding (to bytes for RLP)
public static byte[] ToBytesForRLPEncoding(this int number);
public static byte[] ToBytesForRLPEncoding(this long number);
public static byte[] ToBytesForRLPEncoding(this BigInteger bigInteger);
public static byte[] ToBytesForRLPEncoding(this string str);
public static byte[][] ToBytesForRLPEncoding(this string[] strings);
// Decoding (from RLP bytes)
public static int ToIntFromRLPDecoded(this byte[] bytes);
public static long ToLongFromRLPDecoded(this byte[] bytes);
public static BigInteger ToBigIntegerFromRLPDecoded(this byte[] bytes);
public static string ToStringFromRLPDecoded(this byte[] bytes);
// Utilities
public static byte[] TrimZeroBytes(this byte[] bytes);
}
Related Packages
Used By (Consumers)
RLP is used throughout Nethereum for Ethereum data encoding:
- Nethereum.Signer - Transaction and message signing uses RLP encoding
- Nethereum.Model - Transaction and block models use RLP
- Nethereum.Util - Address derivation uses RLP encoding
- Nethereum.Merkle.Patricia - Patricia Merkle Trie uses RLP for nodes
- Nethereum.RPC - Some RPC methods work with RLP-encoded data
- Nethereum.Consensus - Consensus layer data structures use RLP
Dependencies
- Nethereum.Hex - Hexadecimal encoding/decoding for displaying RLP data
Important Notes
Encoding Behavior
Empty Values
- Empty string/byte array encodes as
0x80 - Decoded empty value returns
null - Zero integer encodes as
0x80(empty byte array)
var empty = RLP.EncodeElement(new byte[0]);
// Result: 0x80
var decoded = RLP.Decode(empty);
// Result: decoded.RLPData == null
Single Bytes
Single bytes in range 0x00-0x7f encode as themselves:
// Character 'd' (0x64) encodes as itself
var encoded = RLP.EncodeElement(new byte[] { 0x64 });
// Result: [0x64]
Big-Endian Encoding
All integers are encoded in big-endian format with leading zeros trimmed:
int value = 1000; // 0x000003e8
var bytes = value.ToBytesForRLPEncoding();
// Result: [0x03, 0xe8] (leading zeros removed)
Threshold Values
The RLP specification uses specific threshold values:
- 56 bytes: Threshold between short and long item encoding
- 0-55 bytes: Use single-byte length prefix (0x80-0xb7 or 0xc0-0xf7)
- 56+ bytes: Use length-of-length prefix (0xb8+ or 0xf8+)
Decoding Collections
When decoding, check the element type:
var decoded = RLP.Decode(encoded);
if (decoded is RLPCollection collection)
{
// It's a list - iterate items
foreach (var item in collection)
{
var value = item.RLPData;
}
}
else
{
// It's a single item
var value = decoded.RLPData;
}
Null vs Empty
- Decoded empty items return
nullfor RLPData - Check for null before using decoded data:
var decoded = RLP.Decode(encoded);
string str = decoded.RLPData?.ToStringFromRLPDecoded() ?? "";
Common Use Cases
Transaction Encoding
Ethereum transactions are RLP-encoded:
// Transaction: [nonce, gasPrice, gasLimit, to, value, data, v, r, s]
var transaction = new List<byte[]>
{
nonce.ToBytesForRLPEncoding(),
gasPrice.ToBytesForRLPEncoding(),
gasLimit.ToBytesForRLPEncoding(),
to.HexToByteArray(),
value.ToBytesForRLPEncoding(),
data.HexToByteArray(),
v.ToBytesForRLPEncoding(),
r,
s
};
var encodedElements = transaction.Select(RLP.EncodeElement).ToArray();
var rlpTransaction = RLP.EncodeList(encodedElements);
Block Header Encoding
Block headers use RLP for hashing:
// Block header fields encoded as RLP list
var headerFields = new List<byte[]>
{
parentHash,
unclesHash,
beneficiary,
stateRoot,
transactionsRoot,
receiptsRoot,
logsBloom,
difficulty.ToBytesForRLPEncoding(),
number.ToBytesForRLPEncoding(),
gasLimit.ToBytesForRLPEncoding(),
gasUsed.ToBytesForRLPEncoding(),
timestamp.ToBytesForRLPEncoding(),
extraData,
mixHash,
nonce
};
var encodedHeader = RLP.EncodeList(
headerFields.Select(RLP.EncodeElement).ToArray()
);
Additional Resources
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net451 is compatible. net452 was computed. net46 was computed. net461 is compatible. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.5.1
- Nethereum.Hex (>= 5.8.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
.NETFramework 4.6.1
- Nethereum.Hex (>= 5.8.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
.NETStandard 2.0
- Nethereum.Hex (>= 5.8.0)
- NETStandard.Library (>= 2.0.3)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
net6.0
- Nethereum.Hex (>= 5.8.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
net8.0
- Nethereum.Hex (>= 5.8.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
net9.0
- Nethereum.Hex (>= 5.8.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
NuGet packages (28)
Showing the top 5 NuGet packages that depend on Nethereum.RLP:
| Package | Downloads |
|---|---|
|
Nethereum.Util
Nethereum Utilities library, including Sha3 Keccack encoding and Address Checksum |
|
|
Nethereum.Signer
Nethereum signer library to sign and verify messages, RLP and transactions using an Ethereum account |
|
|
Nethereum.Model
Nethereum.Model Ethereum Core Model Class Library |
|
|
Nethereum.Merkle.Patricia
Nethereum Merkle Patrica trie and verification |
|
|
Nethereum
Package Description |
GitHub repositories (4)
Showing the top 4 popular GitHub repositories that depend on Nethereum.RLP:
| Repository | Stars |
|---|---|
|
stratisproject/StratisBitcoinFullNode
Bitcoin full node in C#
|
|
|
yc-l/yc.boilerplate
YC. Boilerplate is a set of loose coupling, flexible combination, complete functions, convenient development, and reduces the workload of development.
|
|
|
biheBlockChain/MyLinkToken
开源链克口袋,玩客币钱包
|
|
|
stratisproject/StratisFullNode
|
| Version | Downloads | Last Updated |
|---|---|---|
| 5.8.0 | 1,730 | 1/6/2026 |
| 5.0.0 | 332,910 | 5/28/2025 |
| 4.29.0 | 378,023 | 2/10/2025 |
| 4.28.0 | 67,624 | 1/7/2025 |
| 4.27.1 | 14,488 | 12/24/2024 |
| 4.27.0 | 2,369 | 12/24/2024 |
| 4.26.0 | 158,710 | 10/1/2024 |
| 4.25.0 | 24,871 | 9/19/2024 |
| 4.21.4 | 107,565 | 8/9/2024 |
| 4.21.3 | 20,649 | 7/22/2024 |
| 4.21.2 | 101,887 | 6/26/2024 |
| 4.21.1 | 3,431 | 6/26/2024 |
| 4.21.0 | 15,206 | 6/18/2024 |
| 4.20.0 | 391,732 | 3/28/2024 |
| 4.19.0 | 98,921 | 2/16/2024 |
| 4.18.0 | 324,806 | 11/21/2023 |
| 4.17.1 | 186,197 | 9/28/2023 |
| 4.17.0 | 18,658 | 9/27/2023 |
| 4.16.0 | 127,492 | 8/14/2023 |
| 4.15.2 | 134,722 | 7/11/2023 |
| 4.15.1 | 5,435 | 7/11/2023 |
| 4.15.0 | 5,864 | 7/11/2023 |
| 4.14.0 | 252,619 | 3/19/2023 |
| 4.13.0 | 146,267 | 2/18/2023 |
| 4.12.0 | 286,604 | 12/9/2022 |
| 4.11.0 | 265,047 | 10/27/2022 |
| 4.9.0 | 263,239 | 9/27/2022 |
| 4.8.0 | 250,784 | 8/24/2022 |
| 4.7.0 | 223,782 | 7/20/2022 |
| 4.6.1 | 156,911 | 6/18/2022 |
| 4.6.0 | 13,491 | 6/16/2022 |
| 4.5.0 | 455,645 | 5/13/2022 |
| 4.4.1 | 124,798 | 4/27/2022 |
| 4.4.0 | 17,562 | 4/27/2022 |
| 4.3.0 | 87,535 | 4/12/2022 |
| 4.2.0 | 195,929 | 2/18/2022 |
| 4.1.1 | 609,598 | 11/4/2021 |
| 4.1.0 | 35,121 | 10/15/2021 |
| 4.0.5 | 161,977 | 8/12/2021 |
| 4.0.4 | 10,121 | 8/10/2021 |
| 4.0.3 | 28,475 | 8/8/2021 |
| 4.0.2 | 9,421 | 8/5/2021 |
| 4.0.1 | 16,869 | 7/28/2021 |
| 4.0.0 | 22,574 | 7/26/2021 |
| 3.8.0 | 443,080 | 7/3/2020 |
| 3.7.1 | 140,282 | 2/13/2020 |
| 3.7.0 | 11,717 | 2/13/2020 |
| 3.6.0 | 35,712 | 1/27/2020 |
| 3.5.0 | 27,161 | 12/31/2019 |
| 3.4.0 | 160,348 | 7/29/2019 |
| 3.3.0 | 97,780 | 4/23/2019 |
| 3.2.0 | 72,289 | 4/8/2019 |
| 3.1.2 | 25,356 | 3/13/2019 |
| 3.1.1 | 7,419 | 3/12/2019 |
| 3.1.0 | 28,584 | 3/12/2019 |
| 3.0.0 | 193,477 | 11/28/2018 |
| 3.0.0-rc3 | 6,689 | 10/25/2018 |
| 3.0.0-rc2 | 4,453 | 10/24/2018 |
| 3.0.0-rc1 | 9,819 | 7/25/2018 |
| 2.5.1 | 187,458 | 6/5/2018 |
| 2.5.0 | 5,931 | 6/4/2018 |
| 2.4.0 | 151,415 | 3/11/2018 |
| 2.3.1 | 7,694 | 3/7/2018 |
| 2.3.0 | 6,012 | 3/6/2018 |
| 2.2.3 | 19,157 | 12/16/2017 |
| 2.2.2 | 5,845 | 12/16/2017 |
| 2.2.0 | 5,999 | 12/8/2017 |
| 2.1.0 | 12,947 | 10/23/2017 |
| 2.0.1 | 5,863 | 10/4/2017 |
| 2.0.0 | 16,135 | 9/26/2017 |
| 2.0.0-rc7 | 4,053 | 8/17/2017 |
| 2.0.0-rc6-2 | 3,685 | 7/29/2017 |
| 2.0.0-rc6.1 | 985 | 7/26/2017 |
| 2.0.0-rc5 | 2,735 | 6/19/2017 |
| 2.0.0-rc4 | 3,736 | 6/6/2017 |
| 2.0.0-rc3 | 3,367 | 4/11/2017 |
| 2.0.0-rc2-fix | 2,833 | 4/6/2017 |
| 2.0.0-rc2 | 1,188 | 4/5/2017 |
| 2.0.0-rc1 | 3,323 | 2/8/2017 |