diff --git a/packages/unbreakable_consensus/consensus_test.go b/packages/unbreakable_consensus/consensus_test.go
index 8c0703c31def5278046ad0dbd2b7b118f6f2d004..0f3c91ab349ccad8fdcdf8bbe6b476e33353c038 100644
--- a/packages/unbreakable_consensus/consensus_test.go
+++ b/packages/unbreakable_consensus/consensus_test.go
@@ -23,6 +23,30 @@ func generateElders(totalMana int, nodeCount int) []*social_consensus.Node {
 	return result
 }
 
+func issueTransaction() {
+
+}
+
+func BenchmarkTPS(b *testing.B) {
+	rand.Seed(time.Now().Unix())
+
+	elders := generateElders(10000, 20)
+
+	society := social_consensus.NewSociety(elders)
+	currentTx := social_consensus.NewTransaction()
+
+	b.ResetTimer()
+
+	for i := 0; i < b.N; i++ {
+		tx := social_consensus.NewTransaction()
+		tx.SetIssuer(society.GetRandomElder())
+		tx.SetElder(society.GetRandomElder())
+		tx.Attach(currentTx, currentTx)
+
+		currentTx = tx
+	}
+}
+
 func TestConsensus(t *testing.T) {
 	rand.Seed(time.Now().Unix())
 
@@ -30,9 +54,21 @@ func TestConsensus(t *testing.T) {
 
 	society := social_consensus.NewSociety(elders)
 
-	fmt.Println(society.GetReferencedElderReputation(social_consensus.ElderMask(1).Union(social_consensus.ElderMask(1))))
+	genesis := social_consensus.NewTransaction()
+
+	tx1 := social_consensus.NewTransaction()
+	tx1.SetIssuer(society.GetRandomElder())
+	tx1.SetElder(society.GetRandomElder())
+	tx1.Attach(genesis, genesis)
+
+	tx2 := social_consensus.NewTransaction()
+	tx2.SetIssuer(society.GetRandomElder())
+	tx2.SetElder(society.GetRandomElder())
+	tx2.Attach(tx1, genesis)
+
+	fmt.Println(tx2)
 
-	fmt.Println(society.GetRandomElder().GetElderMask())
+	fmt.Println(society.GetRandomElder())
 
 	/*
 
diff --git a/packages/unbreakable_consensus/social_consensus/transaction.go b/packages/unbreakable_consensus/social_consensus/transaction.go
new file mode 100644
index 0000000000000000000000000000000000000000..18f658962bcc29c2c67a5fc299f798c7b236bd46
--- /dev/null
+++ b/packages/unbreakable_consensus/social_consensus/transaction.go
@@ -0,0 +1,75 @@
+package social_consensus
+
+import (
+	"math/bits"
+
+	"github.com/iotaledger/goshimmer/packages/stringify"
+)
+
+var transactionCounter = 0
+
+type Transaction struct {
+	id                      int
+	claimedRound            int
+	referencedElders        ElderMask
+	seenSuperMajorityElders ElderMask
+	issuer                  *Node
+	elder                   *Node
+	branch                  *Transaction
+	trunk                   *Transaction
+}
+
+func NewTransaction() (result *Transaction) {
+	result = &Transaction{
+		id: transactionCounter,
+	}
+
+	transactionCounter++
+
+	return
+}
+
+func (transaction *Transaction) SetIssuer(issuer *Node) {
+	transaction.issuer = issuer
+}
+
+func (transaction *Transaction) SetElder(elder *Node) {
+	transaction.elder = elder
+}
+
+func (transaction *Transaction) Attach(branch *Transaction, trunk *Transaction) {
+	// update referenced elders
+	transaction.referencedElders = branch.referencedElders.Union(trunk.referencedElders)
+	if transaction.issuer != nil {
+		transaction.referencedElders = transaction.referencedElders.Union(transaction.issuer.GetElderMask())
+	}
+	if transaction.elder != nil {
+		transaction.referencedElders = transaction.referencedElders.Union(transaction.elder.GetElderMask())
+	}
+
+	// update claimed round
+	if branch.claimedRound >= trunk.claimedRound {
+		transaction.claimedRound = branch.claimedRound
+	} else {
+		transaction.claimedRound = trunk.claimedRound
+	}
+
+	if bits.OnesCount64(uint64(transaction.referencedElders)) > 14 {
+		transaction.claimedRound++
+		transaction.referencedElders = branch.referencedElders.Union(trunk.referencedElders)
+	}
+
+	// link transactions together
+	transaction.branch = branch
+	transaction.trunk = trunk
+}
+
+func (transaction *Transaction) String() string {
+	return stringify.Struct("Transaction",
+		stringify.StructField("id", transaction.id),
+		stringify.StructField("issuer", transaction.issuer),
+		stringify.StructField("elder", transaction.elder),
+		stringify.StructField("claimedRound", transaction.claimedRound),
+		stringify.StructField("referencedElders", transaction.referencedElders),
+	)
+}