Ergo Üzerinde Yerel Bir Değişim Ticaret Sistemi
22 Nisan 2019

Yerel bir değişim ticaret sistemi (LETS), üyelerin ortak kredi parası yaratmalarına izin veren yerel bir karşılıklı kredi derneğidir; sistemdeki tüm işlemler ortak bir deftere yazılır. Örneğin, Alice'in sıfır bakiyesi olduğunu ve Bob'dan bir litre çiğ süt almak istediğini varsayalım. Öncelikle, bir fiyat üzerinde anlaşırlar; örneğin, fiyatın yaklaşık 2 Euro olduğunu varsayalım (çünkü Alice ve Bob İrlanda'da yaşıyorlar). İşlem deftere yazıldıktan sonra, Alice'in bakiyesi -2 (eksi iki) Euro olur ve Bob'un bakiyesi 2 Euro olur. Daha sonra Bob, 2 Euro'sunu Charlie'den ev yapımı bir bira almak için harcayabilir. Genellikle, bu tür sistemler negatif bakiyeler üzerinde sınırlamalar getirir ve bazen pozitif bakiyeler üzerinde de sınırlamalar getirir, böylece toplulukta değişimi teşvik eder.
Tarihsel olarak, bu tür sistemler kriz zamanlarında popüler hale gelir. İlk sistem, 1981'de depresyon içinde sıkışmış bir Kanada kasabasında Michael Linton tarafından kurulmuştur. Yerel değişim ticaret sistemleri, 1998-2002 Arjantin Büyük Buhranı sırasında son derece popülerdi. Çoğu LETS grubu 50 ile 250 üye arasında değişmektedir ve kağıt tabanlı kredi notları ve defter, bir çekirdek komite tarafından tutulmaktadır. Ancak, kağıt tabanlı LETS para birimleri, sahte notlar, sistem yöneticilerinin olası kötü davranışları gibi bazı sorunlar göstermiştir. Bu nedenle, blok zinciri tabanlı LETS eski sistemlere göre üstün olabilir. LETS hakkında daha fazla bilgiye "The Ecology of Money" kitabında (Richard Douthwaite tarafından) ve Wikipedia üzerinden ulaşabilirsiniz.
Bu makalede, LETS'in Ergo üzerinde nasıl uygulanabileceğini gösteriyoruz. Bildiğimiz kadarıyla, bu tür bir topluluk parasının blok zinciri üzerinde ilk uygulamasıdır. Referans uygulamamız basittir ve bir yönetim sözleşmesi ve bir değişim sözleşmesi olmak üzere iki sözleşmeden oluşmaktadır. Ergo ön bilgilerini atlıyoruz, bu nedenle lütfen ICO makalesini ve ErgoScript eğitimlerini (temel ve ileri) okuyun. Yine de, aşağıdaki cümlelerde birkaç yeni terim tanıtacağız. Eğer bir token, bir miktar ile çıkarılmışsa, buna singleton token diyoruz. Benzer şekilde, singleton token'ı içeren bir kutuya singleton kutu denir.
Yönetim sözleşmesi, LETS sisteminin üyelerini tutan bir singleton kutusunu kontrol etmektedir. Sözleşme, yeni üyelerin bir işlem başına bir üye hızıyla eklenmesine olanak tanır. Kutu, üyeleri saklamaz, yalnızca üyelerin dizini üzerine inşa edilmiş kimlik doğrulama verilerinin küçük bir özetini saklar. Bir üye, dizine üye ekleyen bir işlemde çıkarılan bir singleton token ile ilişkilendirilir. İşlem, üyenin singleton token'ını içeren yeni bir üye kutusu oluşturur. Üyenin kutusu, değişim sözleşmesi tarafından korunmaktadır. Ayrıca, yeni oluşturulan üye kutusunun başlangıç bakiyesi R4 kaydına yazılmıştır ve örneğimizde bakiye sıfıra eşittir. Yeni bir üye oluşturan işlem, dizin dönüşümü için bir doğrulama kanıtı sağlamalıdır.
Yönetim sözleşmesi kutusu genellikle bir komite tarafından kontrol edilir ve komite zamanla evrim geçirebilir. Bunu desteklemek için, komite mantığının R5 kaydında yer almasına izin veriyoruz. Örneğin, yeni bir komite üyesinin yeni bir LETS üyesi ile birlikte eklendiğini varsayalım; giriş yönetim sözleşmesi kutusu 2-3 imza gerektirirken, çıkış kutusu 3-4 imza gerektirir. Bu durumda, giriş ve çıkış kutusundaki R5 kaydının içeriği farklı olacaktır.
Aşağıda, yorumlarla birlikte ErgoScript'teki yönetim sözleşmesi kodu verilmiştir. Lütfen "userContractHash"'ın değişim sözleşmesi hash'ı ile ilgili olduğunu unutmayın.
val selfOut = OUTPUTS(0)
// Yönetim scripti
val managementScript = selfOut.R5[SigmaProp].get
// Yönetim scripti şablonu kendisini çoğaltıyor ve yönetim scripti tatmin ediliyor
val scriptCorrect = (selfOut.propositionBytes == SELF.propositionBytes) && managementScript
// Harcama işlemi, dizin, kullanıcı, ücret için kutular oluşturuyor.
val outsSizeCorrect = OUTPUTS.size == 3
// Yönetim etiket token'ının kendisini çoğalttığını kontrol eder
val outTokenCorrect = (selfOut.tokens.size == 1) && (selfOut.tokens(0)._1 == letsToken)
// Yeni token'ın çıkarıldığını ve miktarının doğru olduğunu kontrol eder
// OUTPUTS(0) token'ları zaten outtokenCorrect ile kontrol edildi
val issuedTokenId = INPUTS(0).id
val userOut = OUTPUTS(1)
val correctTokenAmounts =
(userOut.tokens.size == 1 &&
userOut.tokens(0)._1 == issuedTokenId &&
userOut.tokens(0)._2 == 1 &&
OUTPUTS(2).tokens.size == 0 &&
outTokenCorrect)
// Yeni kullanıcının sıfır bakiyesi ile oluşturulduğunu kontrol eder
val zeroUserBalance = userOut.R4[Long].get == 0
val properUserScript = blake2b256(userOut.propositionBytes) == userContractHash
// Yeni token tanımlayıcısının dizine eklendiğini kontrol eder
val selfTree = SELF.R4[AvlTree].get
val toAdd: Coll[(Coll[Byte], Coll[Byte])] = Coll((issuedTokenId, Coll[Byte]()))
val proof = getVar[Coll[Byte]](1).get
val modifiedTree = selfTree.insert(toAdd, proof).get
val expectedTree = selfOut.R4[AvlTree].get
val treeCorrect = modifiedTree == expectedTree
correctTokenAmounts && scriptCorrect && treeCorrect && zeroUserBalance && properUserScript
correctTokenAmounts && scriptCorrect && treeCorrect && zeroUserBalance && properUserScript correctTokenAmounts && scriptCorrect && treeCorrect && zeroUserBalance && properUserScript
Değişim sözleşmesi scripti oldukça basittir ve mantığını açıklayan yorumlarla birlikte aşağıda verilmiştir. Sözleşmede, bir değişim sözleşmesi kutusu için harcama işleminin en az iki girdi alması gerektiği varsayılmaktadır ve ilk iki girdi, değişim sözleşmesi scripti tarafından korunmalı ve LETS üye token'larını içermelidir. Girdilerdeki singleton üye token'larının gerçekten LETS sistemine ait olduğunu kontrol etmek için, bir harcama işlemi yönetim sözleşmesi kutusunu ilk salt okunur veri girişi olarak sağlar ve ayrıca üye token'larının yönetim sözleşmesi kutusunun R4 kaydı aracılığıyla kimlik doğrulaması yapılmış dizine ait olduğunu kanıtlamalıdır. Scriptteki "letsToken", yönetim kutusunun singleton token'ı ile ilgilidir.
// LETS tüccarı için izin verilen minimum bakiye
val minBalance = -20000
val lookupProof = getVar[Coll[Byte]](1).get
// LETS üyelerinin dizinini içeren salt okunur kutu
val treeHolderBox = CONTEXT.dataInputs(0)
val properLetsToken = treeHolderBox.tokens(0)._1 == letsToken
val membersTree = treeHolderBox.R4[AvlTree].get
// Harcama işlemi, bir anlaşma yapmak isteyen iki LETS üyesinin kutularını alır
// ve değiştirilmiş bakiyelerle kutular döndürür.
val participant0 = INPUTS(0)
val participant1 = INPUTS(1)
val participantOut0 = OUTPUTS(0)
val participantOut1 = OUTPUTS(1)
// Üyelerin gerçekten LETS'e ait olduğunu kontrol eder
val token0 = participant0.tokens(0)._1
val token1 = participant1.tokens(0)._1
val memberTokens = Coll(token0, token1)
val membersExist = membersTree.getMany(memberTokens, lookupProof).forall({ (o: Option[Coll[Byte]]) => o.isDefined })
// LETS üyesinin anlaşma sırasında bakiye değişikliklerinin doğru olduğunu kontrol eder
val initialBalance0 = participant0.R4[Long].get
val initialBalance1 = participant1.R4[Long].get
val finishBalance0 = participantOut0.R4[Long].get
val finishBalance1 = participantOut1.R4[Long].get
val diff0 = finishBalance0 - initialBalance0
val diff1 = finishBalance1 - initialBalance1
val diffCorrect = diff0 == -diff1
val balancesCorrect = (finishBalance0 > minBalance) && (finishBalance1 > minBalance) && diffCorrect
// Üye kutularının scriptlerini kaydettiğini kontrol eder.
// todo: burada optimizasyon yapılabilir
val script0Saved = participantOut0.propositionBytes == participant0.propositionBytes
val script1Saved = participantOut1.propositionBytes == participant1.propositionBytes
val scriptsSaved = script0Saved && script1Saved
// Üye özel kutu koruması
val selfPubKey = SELF.R5[SigmaProp].get
selfPubKey && properLetsToken && membersExist && diffCorrect && scriptsSaved
Her iki sözleşmenin de farklı özelliklere sahip yeni sistemler elde etmek için birçok şekilde değiştirilebileceğini unutmayın. Umarım bir gün bu makale devam eder!
Share post
13 Ağustos 2025
9 Temmuz 2025
12 Mayıs 2025






