Generic Transaction Protocol (GTX)
The Generic Transaction Protocol (GTX) is a protocol built on top of the Generic Transfer Value (GTV). It focuses on how to encode transactions in a way that Postchain can accurately comprehend.
While Postchain relies on GTX for sending and receiving transactions, and it is possible to construct various Rell types directly into GTV, direct GTV usage is not recommended for transaction construction.
GTX provides three essential features that make it powerful and flexible:
- Standard ASN.1 DER serialization, backed by ITU-T, ISO, and IEC
- Built-in support for multi-signature transactions
- Native atomic transaction handling
A GTX transaction operates through operations, where each operation has a name and a list of arguments. For example:
issue(<Alice account ID>, 1000, USD)
transfer(<Alice account ID>, <Bob account ID>, 100, USD)
This structure functions like a Remote Procedure Call (RPC) system - the client submits operations to be executed by Postchain nodes. Each GTX transaction can contain multiple operations, and all operations within a transaction are atomic: they either all succeed or all fail together.
GtxMessages DEFINITIONS ::= BEGIN
IMPORTS RawGtv FROM GtvMessages;
-- All types are using the same tags as RawGtv to make gtv<->gtx encoding equivalent
-- Gtx operation
-- [ string, [ gtv ] ]
RawGtxOp ::= [5] EXPLICIT SEQUENCE {
name [2] EXPLICIT UTF8String, -- RawGtv { string } --
args [5] EXPLICIT SEQUENCE OF RawGtv -- RawGtv { array } --
}
-- Gtx Body
-- [ bytearray, [ gtxOp ], [ bytearray ] ]
RawGtxBody ::= [5] EXPLICIT SEQUENCE {
blockchainRid [1] EXPLICIT OCTET STRING, -- RawGtv { bytearray } --
operations [5] EXPLICIT SEQUENCE OF RawGtxOp,
signers [5] EXPLICIT SEQUENCE OF [1] EXPLICIT OCTET STRING -- RawGtv { bytearray} --
}
-- Gtx
-- [ gtxBody, [ bytearray] ]
RawGtx ::= [5] EXPLICIT SEQUENCE {
body RawGtxBody,
signatures [5] EXPLICIT SEQUENCE OF [1] EXPLICIT OCTET STRING -- RawGtv { bytearray } --
}
END
Generic Transfer Value (GTV)
The Generic Transfer Value (GTV) protocol serves as the foundation for data serialization in Postchain. It supports a comprehensive range of data types:
- Primitive types: integers, strings, byte arrays, and more
- Complex types: arrays and dictionaries only
All GTV data is serialized using the ASN.1 DER format for transmission.
GtvMessages DEFINITIONS ::= BEGIN
DictPair ::= SEQUENCE {
name UTF8String,
value RawGtv
}
RawGtv ::= CHOICE {
null [0] NULL,
byteArray [1] OCTET STRING,
string [2] UTF8String,
integer [3] INTEGER,
dict [4] SEQUENCE OF DictPair,
array [5] SEQUENCE OF RawGtv,
bigInteger [6] INTEGER
}
END
Type conversions
The following table shows how Rell types are converted to and from GTV types in different contexts:
Rell type | Operation input | Query input | Query Output |
---|---|---|---|
entity | GtvInteger | GtvInteger | GtvInteger |
enum | GtvInteger | GtvInteger (can also be GtvString) | GtvString |
struct | GtvArray | GtvArray (can also be GtvDict) | GtvDict |
integer | GtvInteger | GtvInteger | GtvInteger |
big_integer | GtvBigInteger | GtvBigInteger | GtvBigInteger |
decimal | GtvString | GtvString | GtvString |
boolean | GtvInteger | GtvInteger | GtvInteger |
rowid | GtvInteger | GtvInteger | GtvInteger |
json | GtvString | GtvString | GtvString |
text | GtvString | GtvString | GtvString |
byte_array | GtvByteArray | GtvByteArray | GtvByteArray |
nullable | GtvNull or Type | GtvNull or Type | GtvNull or Type |
collection | GtvArray | GtvArray | GtvArray |
text map | GtvDict | GtvDict | GtvDict |
non-text map (e.g., [[k1, v1], [k2, v2], ...] ) | GtvArray | GtvArray | GtvArray |
named tuple (e.g., (x = 1, y = 2, z = 3) ) | GtvDict | GtvDict | GtvDict |
unnamed tuple (e.g., (1, 2, 3) ) | GtvArray | GtvArray | GtvArray |
Strict type conversion
With Rell Version 0.13.9, type conversion has become stricter by default. The following table shows the differences between strict and non-strict type handling:
Operation input Rell type | Accepted types in strict | Accepted types in non-strict |
---|---|---|
byte_array | GtvByteArray | GtvByteArray |
GtvString | ||
integer | GtvInteger | GtvInteger |
GtvBigInteger | ||
big_integer | GtvBigInteger | GtvBigInteger |
GtvInteger | ||
decimal | GtvString | GtvString |
GtvInteger | ||
GtvBigInteger | ||
rowid | GtvInteger | GtvInteger |
Next up
Next, we'll examine how all the technologies discussed so far integrate to create a platform for dapp developers. We'll explore the various components of a dapp on Chromia and provide guidance on how you, as a developer, can get started quickly and easily.