SEP: 0028
Title: XDR Base64 Encoding
Author: Leigh McCulloch <@leighmcculloch>
Status: Final
Created: 2019-12-19
Updated: 2019-12-19
Version: 1.0.0
On the Stellar network, XDR messages such as transaction envelopes, transaction results, and others are often encoded into base64. This is a common best practice that makes the binary messages portable, embeddable in other message formats such as JSON, and is often required by other SEPs.
Base64 encoders are available in the standard libraries of many programming languages and are relatively consistent. Base64 decoders are just as available but are less consistent. Some languages contain base64 decoders that are very strict about aspects such as padding, while others are less strict. As an example, base64 that has had its padding removed will be parseable in JavaScript, Java, and Ruby, but will error in Python and Go. Because of this it is important that when base64-encoding XDR messages that they are consistently encoded according to the specification below, and unaltered. Following the specification below should be low effort because many programming languages' standard libraries support this form of encoding by default, and this specification serves to capture current expectations.
XDR messages when base64-encoded should follow the specification in RFC4648 Section 4.
The alphabet to use for encoding is the standard alphabet utilizing the A-Z
a-z
0-9
+
/
character set for value encoding, and =
for padding.
Special characters in the alphabet should not be substituted for alternative alphabets such as the URL or Filename Safe Alphabet described in the RFC's Section 5.
Padding must always be used, and never removed from the message.
Line feeds should not be added to the base64-encoded data.
Base64 Encoded Message:
AAAABgABAvD+/wAA
Decoded Message:
00000000 00 00 00 06 00 01 02 f0 fe ff 00 00 |............|
[]byte{0x0, 0x0, 0x0, 0x6, 0x0, 0x1, 0x2, 0xf0, 0xfe, 0xff, 0x0, 0x0}
Base64 Encoded Message:
AAAABAABAvA=
Decoded Message:
00000000 00 00 00 04 00 01 02 f0 |........|
[]byte{0x0, 0x0, 0x0, 0x4, 0x0, 0x1, 0x2, 0xf0}
Base64 Encoded Message:
AAAACgABAvD+/wAAAAAAAA==
Decoded Message:
00000000 00 00 00 0a 00 01 02 f0 fe ff 00 00 00 00 00 00 |................|
[]byte{0x0, 0x0, 0x0, 0xa, 0x0, 0x1, 0x2, 0xf0, 0xfe, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
Base64 Encoded Message:
AAAASwD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wA=
Decoded Message:
00000000 00 00 00 4b 00 fe ff 00 fe ff 00 fe ff 00 fe ff |...K............|
00000010 00 fe ff 00 fe ff 00 fe ff 00 fe ff 00 fe ff 00 |................|
00000020 fe ff 00 fe ff 00 fe ff 00 fe ff 00 fe ff 00 fe |................|
00000030 ff 00 fe ff 00 fe ff 00 fe ff 00 fe ff 00 fe ff |................|
00000040 00 fe ff 00 fe ff 00 fe ff 00 fe ff 00 fe ff 00 |................|
[]byte{0x0, 0x0, 0x0, 0x4b, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0, 0xfe, 0xff, 0x0}
AAAACgABAvD+/wAAAAAAAA
AAAACgABAvD-_wAAAAAAAA==
AAAASwD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wD+
/wD+/wD+/wD+/wD+/wD+/wD+/wD+/wA=
These examples of base64-encoding XDR messages perform the encoding per the above specification. These are examples, not an exhaustive list of all programming langauges that are known to support the standard.
import "encoding/base64"
base64.StdEncoding.EncodeToString(xdrBytes)
import java.util.Base64;
Base64.getEncoder().encodeToString(xdrBytes)
import base64
base64.b64encode(xdr_bytes)