GET Documentation — State change receipts

KasperK
Open Ticketing Ecosystem
6 min readFeb 27, 2020

The GET Protocol makes certain information about tickets and event sales is publically available. The availability and access to the event and ticket data are made immutable by registering the data on the blockchain. By blockchain developer Kasper Keunen.

In this blog, we will explain how we achieve these goals using the structure and properties of ‘stating change receipts’.

A single state change defined

If a ticket is scanned or sold it changes state. This action effectively means that its new state the asset has different properties as before the state change.

The diagram below shows the process of an execution moving from the “Sold” place/state, to the “Resale” state via the “forSale” firing. Then the execution moves back to the “Sold” state via the “buy” firing. These 2 state changes would evidently produce 2 state change receipts.

In order to spread to the network that a certain change has occurred, receipts can be read by all actors. This is achieved with the help of receipt batches.

Receipt batches?

State change receipts are stored in Receipt Batches. The blog linked below provides details on what these are and how they are stored.

TLDR State change batches: All you need to know about the IPFS batches is that they are stored and sequenced in an immutable manner in a smart contract (here). A receipt contains 4 data points (on a single line in the batch). The code snippet shown below shows 6 state change receipts (second hash is shortened as to better fit the blog page).

zFsGM283o6E2SurYVLoZoVyDGKT78ausQGcyBZCWnzumr,zFsGM28F....,f,0
zFsGM28eNuoCzk7ouebPfBAzaH6XoMsJSYhMYMsGAiXtW,zFsGM28F.....,f,0
zFsGM26otRif88cVpUP5r72Me6Ze1JybrfSbiPhkJW6ks,zFsGM283.....,f,13
zFsGM262GY1aBnsEy7PpLyNRDkaUXSnYKuyjFTTjrqf3Y,zFsGM28e.....,f,13
zFsGM28HyJ6aT4zXkajepuWmsyZBgUfBScMK6VPUEyJwL,zFsGM262.....,f,2
zFsGM26TsUUzUkXxrKMp4bpGwiSAPxwx8G6eWF8A4D7Qf,zFsGM26o.....,f,2

Unpacking a state change receipt

A state change receipt contains 4 pieces of data. Let’s take for example the following receipt:

[zFsGM26zwhxGkTRhrVZsb24ySdofZh4snQyk4RcT4DLYg,zFsGM26LWQdSpmjzHdVdpJGVd54cLZYQ7xhYeQMz9uWCJ,f,2]

2 hashes, a string and an integer. How interesting. What do the variables of a state change do they encode? Here we go:

[zFsGM26zwhxGk...,zFsGM26LWQdSp...,f,2]  -> written as[statehash, previous_statehash, type_of_statechange , id_of_firing]

Every state change receipt is structured in the exact same way (both for wirings as for firings!).

Definitions of receipt variables

A. statehash: This is a hash of a executions state change that of the receipt. Statehashes are unique identifiers of a certain execution in a wiring. Statehashes belong to

B. previous_statehash: This is the statehash of the state change of the execution in its previous state.

This means that a previous_statehash(B) was the statehash of the execution at t:n-1. So a verifier can find the preceding receipt of a certain execution by querying preceding IPFS batches to find this previous state change.

C. type_of_statechange: The type of state change that has taken place. There are two types of actions, wirings(indicated with a: ‘w’) and firings(indicated with a: ‘f’).

D. id_of_firing: Depending on the type of state change that occurred, this field points to the id of the firing that was executed in the state change. This data point can only be interpreting it alongside the wiring instructions of the event. Read more about wiring(instructions) in the 2 blogs linked below (both blog

Creating executions

[blog/ifno not yet public — awaiting the addition of enhanced authentication by Statebox]

Communicating with a wiring

[blog/ifno not yet public — awaiting the addition of enhanced authentication by Statebox]

Linking the receipts

Who is the first? Who is second? We need order. Receipts need to be sequenced for them to make any sense.

With only a single state change receipt no information can be inferred about a ticket or its execution.

A ticket explorer node needs to collect the full history of all the state changes of an execution. Only then anything can be concluded on a ticket's current state (and possible future states). This means a ticket explorer node needs to collect:

  • All state changes an execution has undergone (amount state changes unknown)
  • The wiring of the event in which the execution was created (1 state change)

Remember: Every state change receipt points to the previous stateHash as displayed in the diagram below.

A blockchain part of tickets(executions) history consists of a series of state change receipts.

There is a lot going on in the diagram displayed above. However, the processes displayed are repetitive. The diagram shown below zooms in on a single state change receipt and how it points to a stateHash in a preceding IPFS batch.

What is the history of a ticket execution?

Remember that all the state change receipts are structured in a repeating structure.

A: (stateHash t=n),B: (stateHash t=n-1), C: type: f=firing , D: 2 

To find the previous state of this execution the ticket explorer will need to query the value found in B: (stateHash t=n-1) on the first position of a mutation receipt in a preceding IPFS batch.

As the previous stateHash (B) will be the ‘current stateHash (A)’ of the mutation receipt in a preceding IPFS batch. In pseudo-code we are looking for a mutation receipt with B on the first position:

IN BATCH FIND * WHERE A = (stateHash & t=n) FOR BATCHES WHERE t<n

Below you find the output of such a query. In bold context is provided.

27DiJvDmjtAHwHxU5a7s5zzf8MEbBJF9NUu6mvaG,zFsGM27VMNWZne1SSkWnDQTzr6TdjmsKpbxGkJKKaEC8e,w,0  -> Event wiring state change receiptzFsGM28J4Vh7ycAHvaHzy4SyyQiZ1nwYjGdZK71VbcQ9A,zFsGM27DiJvDmjtAHwHxU5a7s5zzf8MEbBJF9NUu6mvaG,f,0 -> Initial firing of executionzFsGM273hfXgKWXanz3v8UqYzdy8Rc8dRPzqkc2JvnJ5Z,zFsGM28J4Vh7ycAHvaHzy4SyyQiZ1nwYjGdZK71VbcQ9A,f,13 -> State change 2ndzFsGM289462RDKVqkZ8MRDapH2ZWuvqBGgLXieidVN4hy,zFsGM273hfXgKWXanz3v8UqYzdy8Rc8dRPzqkc2JvnJ5Z,f,2 -> State change 3rdzFsGM27bm6Ur4v2TgRwX1XHDd3F96kdTDEA2VeJKKcBos,zFsGM289462RDKVqkZ8MRDapH2ZWuvqBGgLXieidVN4hy,f,6 -> State change 4thzFsGM26PgU7eP2uHyB7TsSBxAnXADZDm2bspRL71EvvMN,zFsGM27bm6Ur4v2TgRwX1XHDd3F96kdTDEA2VeJKKcBos,f,3 -> State change 5thzFsGM26FJ3XVFETU3vWtFJP9nQuTgT4HxE6th598zMrty,zFsGM26PgU7eP2uHyB7TsSBxAnXADZDm2bspRL71EvvMN,f,11 -> State change 6th

The result above shows 6 state changes and 1 wiring receipt. If we would add the timestamp of the IPFS batch that anchors these state changes we would be able to create a timeline for this ticket.

What do we know now?

Without any additional data about the event or this ticket, we can only conclude that ‘a’ ticket changed state 6 times (including the exact times of each state change).

If we want to know more about what these state changes exactly entailed, a verifier needs to know the wiring instruction. This is similar to Ethereum/Solidity, a contract call only makes for an observer when they know what code is being run. With GET all wiring instructions are public by default, how this works in detail is explained in the blog covering wiring linked below:

[blog/info not yet public — awaiting the addition of enhanced authentication by Statebox]

transitions = {
0: 'init_create',
1: 'fire_block',
2: 'fire_buy',
3: 'fire_buy_',
4: 'fire_buyBack',
5: 'fire_cancel',
6: 'fire_forSale',
7: 'fire_noShow',
8: 'fire_notResold',
9: 'fire_notSold',
10: 'fire_notSold2',
11: 'fire_scan',
12: 'fire_showOver',
13: 'fire_unblock',
}
transitions = {
0: 'init_create',
1: 'fire_block',
2: 'fire_buy',
3: 'fire_buy_',
4: 'fire_buyBack',
5: 'fire_cancel',
6: 'fire_forSale',
7: 'fire_noShow',
8: 'fire_notResold',
9: 'fire_notSold',
10: 'fire_notSold2',
11: 'fire_scan',
12: 'fire_showOver',
13: 'fire_unblock',
}

With this mapping, you have a precise history of how ‘a’ ticket changed state over time. So this will leave us with:

zFsGM27DiJvDmjtAHwHxU5a7s5zzf8MEbBJF9NUu6mvaG,zFsGM27VMNWZne1SSkWnDQTzr6TdjmsKpbxGkJKKaEC8e,w,0  -> Event wiring state change receiptzFsGM28J4Vh7ycAHvaHzy4SyyQiZ1nwYjGdZK71VbcQ9A,zFsGM27DiJvDmjtAHwHxU5a7s5zzf8MEbBJF9NUu6mvaG,f,0 -> 1st: Ticket Create zFsGM273hfXgKWXanz3v8UqYzdy8Rc8dRPzqkc2JvnJ5Z,zFsGM28J4Vh7ycAHvaHzy4SyyQiZ1nwYjGdZK71VbcQ9A,f,13 -> 2nd: Ticket Unblocked zFsGM289462RDKVqkZ8MRDapH2ZWuvqBGgLXieidVN4hy,zFsGM273hfXgKWXanz3v8UqYzdy8Rc8dRPzqkc2JvnJ5Z,f,2 -> 3rd: Ticket BuyzFsGM27bm6Ur4v2TgRwX1XHDd3F96kdTDEA2VeJKKcBos,zFsGM289462RDKVqkZ8MRDapH2ZWuvqBGgLXieidVN4hy,f,6 -> 4th: Ticket forSalezFsGM26PgU7eP2uHyB7TsSBxAnXADZDm2bspRL71EvvMN,zFsGM27bm6Ur4v2TgRwX1XHDd3F96kdTDEA2VeJKKcBos,f,3 -> 5th: Ticket Buy_

[blog/info not yet public — awaiting the addition of enhanced authentication by Statebox]

More about the GET Protocol

More about the GET Protocol

Any questions or want to know more about what we do? Join our active Telegram community for any questions you might have, read our whitepaper, visit the website, join the discussion on the GET Protocol Reddit. Or get yourself a smart event ticket in our sandbox environment. Download the GUTS Tickets app on iOS or Android.

--

--