Sistem Perdagangan Lokal Tanpa Kepercayaan
29 Mei 2019

Sistem Perdagangan Lokal (LETS) bertujuan untuk mengembangkan ekonomi lokal dan biasanya digunakan oleh orang-orang di suatu daerah yang saling berdekatan. Untuk gambaran singkat tentang LETS lihat tautan ini, yang juga menjelaskan implementasi ErgoScript dari LETS yang dikelola oleh komite. Kami menyebut sistem semacam itu sebagai dikelola atau berizin, karena bergantung pada komite anggota tepercaya untuk mendaftarkan anggota baru ke dalam LETS.
Di sini kami menjelaskan LETS tanpa kepercayaan, yaitu, satu di mana tidak ada komite manajemen yang diperlukan untuk pendaftaran.
Gambaran Umum
LETS melibatkan beberapa pihak yang setuju untuk menggunakan beberapa bentuk "mata uang lokal", biasanya dipatok pada mata uang utama negara dengan rasio 1:1. Anggaplah LETS kami berbasis di negara Eropa di mana mata uangnya adalah Euro, dan pertukaran dilakukan dalam "Euro lokal", yang dianggap setara dengan Euro nasional.
Setiap pengguna di LETS memiliki akun, yang berisi saldo LETS pengguna tersebut (dalam Euro Lokal). Saat bergabung, setiap pengguna memiliki saldo nol. Saldo disimpan dalam buku besar (mungkin terdesentralisasi). Fitur menarik dari LETS adalah bahwa pengguna dengan saldo nol juga dapat "menarik" uang, tetapi hanya untuk membayar pengguna LETS lainnya. Pada setiap saat jumlah saldo LETS dari semua pengguna adalah nol.
Sebagai contoh, Alice dengan saldo nol ingin membeli satu liter susu seharga 2 Euro dari Bob yang juga merupakan anggota LETS dengan saldo nol. Dia mentransfer 2 Euro dari akunnya ke akun Bob, membuat saldonya -2 dan saldo Bob +2. Bob kemudian dapat mentransfer sebagian atau seluruh saldonya ke pengguna LETS lainnya sebagai imbalan untuk barang atau jasa.
LETS Tanpa Kepercayaan
Karena kami menginginkan LETS tanpa kepercayaan, kami tidak dapat bergantung pada kelompok orang tepercaya untuk menerima pengguna. Perhatikan bahwa kami masih akan memiliki komite untuk melakukan beberapa tugas seperti mengatur parameter LETS (mata uang lokal, jumlah maksimum anggota, dll) dan mengkonsumsi biaya pendaftaran.
Kami hanya akan mengasumsikan oracle harga yang tepercaya yang memberikan tarif euro saat ini ke erg yang diidentifikasi oleh beberapa id global (rateTokenID) dan kotak singleton yang berisi tepat satu token dengan id ini. Kotak singleton, yang dijelaskan di sini, adalah kotak yang berisi token singleton, yaitu, token dengan hanya satu kuantitas yang ada. Kotak ini juga berisi tarif erg ke euro pada periode waktu tertentu. Tarif diperbarui dengan menghabiskan kotak ini dan membuat kotak singleton lain dengan tarif baru.
Pada setiap saat, LETS kami didefinisikan secara unik oleh kotak token global yang berisi beberapa token keanggotaan dengan id letsTokenID. Kotak ini mendefinisikan parameter LETS seperti lokasi, unit mata uang, rateTokenID, dll. Kotak token awalnya dimulai dengan, katakanlah, 10000 token keanggotaan. Pengguna dapat menghabiskan kotak ini dan membuat kotak LETS individu mereka sebagai keluaran dari transaksi, sehingga setiap keluaran tersebut memiliki tepat satu token keanggotaan dan token keanggotaan yang tersisa dimasukkan ke dalam kotak token yang baru dibuat.
Kotak LETS mewakili anggota LETS dan harus digunakan dalam setiap transaksi. Untuk kesederhanaan, artikel ini membatasi semua transaksi LETS untuk melibatkan tepat dua anggota, satu sebagai pengirim dan yang lainnya sebagai penerima, sehingga pengirim mentransfer sejumlah positif dari mata uang LETS (euro lokal) kepada penerima. Transaksi semacam itu mengkonsumsi kotak anggota dan membuatnya kembali sebagai keluaran dengan saldo yang diperbarui.
Varian Dasar
Untuk mencegah spam dan serangan DDoS, kami memerlukan setidaknya sejumlah minimum erg (minErgsToJoin) untuk dikunci di kotak anggota yang baru dibuat. Erg akan dikunci sampai setidaknya minWithdrawTime jumlah blok telah ditambang. Sebuah kotak diperbolehkan memiliki saldo LETS negatif hingga jumlah yang dapat ditutupi oleh erg yang terkunci (menggunakan tarif pada saat perdagangan).
// kotak token menyimpan token keanggotaan dan memiliki skrip ini
val tokenBox = OUTPUTS(0) // keluaran pertama juga harus berupa kotak token
// keluaran pertama berisi sisa token LETS
def isLets(b:Box) = { // mengembalikan true jika b adalah kotak LETS
// Kotak LETS harus memiliki tepat 1 token keanggotaan di tokens(0)
b.tokens(0)._1 == letsTokenID && b.tokens(0)._2 == 1 &&
blake2b256(b.propositionBytes) == memberBoxScriptHash &&
SELF.R4[Long].get == 0 && // mulai kotak dengan saldo LETS nol
b.value >= minErgsToJoin && // kotak harus mengandung beberapa minimum erg
b.R6[Long].get <= HEIGHT // simpan tinggi pembuatan di R6
}
// berapa banyak kotak lets yang dibuat dalam tx
val numLetsBoxes = OUTPUTS.filter({(b:Box) => isLets(b)}).size
// Dalam transaksi berikut ini dipertahankan untuk kotak token ...
tokenBox.tokens(0)._1 == SELF.tokens(0)._1 && // id token
tokenBox.tokens(0)._2 == SELF.tokens(0)._2 - numLetsBoxes && // kuantitas
tokenBox.propositionBytes == SELF.propositionBytes // skrip
Kotak anggota LETS dilindungi oleh skrip di bawah ini, yang hash-nya memberBoxScriptHash digunakan di atas. Skrip ini memerlukan tepat satu pasangan (pengirim, penerima) per transaksi.
val validRateOracle = CONTEXT.dataInputs(0).tokens(0)._1 == rateTokenID
val rate = CONTEXT.dataInputs(0).R4[Int].get
val inBalance = SELF.R4[Long].get // saldo LETS dari input saat ini
val pubKey = SELF.R5[SigmaProp].get // pemilik input saat ini
val createdAt = SELF.R6[Long].get // tinggi di mana input saat ini ditambang
val index = getVar[Int](0).get // indeks dari keluaran yang sesuai
val out = OUTPUTS(index)
val outBalance = out.R4[Long].get // saldo LETS dari keluaran
// Kotak LETS adalah kotak yang memiliki skrip yang sama dengan kotak saat ini
val isMemberBox = {(b:Box) => b.propositionBytes == SELF.propositionBytes}
val letsInputs = INPUTS.filter(isMemberBox) // semua kotak input LETS
val letsOutputs = OUTPUTS.filter(isMemberBox) // semua kotak output LETS
// Input saat ini milik penerima jika saldo LETS-nya meningkat
// Mungkin ada beberapa erg di kotak input penerima. Kami perlu memastikan bahwa
// kotak output penerima juga mengandung jumlah erg yang sama seperti input
val receiver = outBalance > inBalance && out.value == SELF.value
val getBalance = {(b:Box) => b.R4[Long].get} // mengembalikan saldo LETS dari sebuah kotak
val letsBalIn = letsInputs.map(getBalance).fold(0L, {(l:Long, r:Long) => l + r})
val letsBalOut = letsOutputs.map(getBalance).fold(0L, {(l:Long, r:Long) => l + r})
// kotak pengirim dapat mengandung jumlah erg yang lebih sedikit (pengirim dapat menarik erg yang disediakan
// bahwa saldo LETS negatif dari pengirim di keluaran didukung oleh erg yang cukup)
val correctErgs = out.value >= -outBalance * rate && (
out.value >= SELF.value || SELF.R6[Long].get + minWithdrawTime > HEIGHT
)
// untuk penerima, kami tidak menyentuh saldo erg,
// karena penerima tidak terlibat secara aktif dalam transaksi
inBalance != outBalance && // beberapa transaksi harus terjadi; saldo harus berubah
SELF.tokens(0)._1 == letsTokenID && // input saat ini memiliki token yang benar
out.tokens(0)._1 == letsTokenID && // keluaran yang sesuai memiliki token yang benar
validRateOracle && // oracle yang menyediakan tarif memiliki "token tarif" yang benar
letsBalIn == letsBalOut && // total saldo LETS dipertahankan dalam transaksi
letsInputs.size == 2 && letsOutputs.size == 2 && // hanya dua input LETS, keluaran
out.propositionBytes == SELF.propositionBytes && // keluaran adalah kotak LETS ...
out.R5[SigmaProp].get == pubKey && // ... dengan kunci publik yang benar
out.R6[Long].get == SELF.R6[Long].get && // ... dan tinggi pembuatan
(receiver || // baik input saat ini milik penerima ...
(pubKey && correctErgs) // ... atau keluaran memiliki erg yang benar dan tx memiliki tanda tangan
)
Transaksi yang menghabiskan kotak dengan skrip di atas memerlukan:
- Jumlah saldo LETS dari input dan keluaran dipertahankan
- Terdapat dua input LETS dan dua keluaran LETS
- Kunci publik (disimpan di R5) dipertahankan di keluaran yang sesuai
- Tinggi pembuatan (disimpan di R6) dipertahankan di keluaran yang sesuai
Kami mengatakan bahwa beberapa kunci publik adalah penerima jika saldo LETS dari keluaran lebih tinggi daripada saldo inputnya.
Kondisi terakhir mengharuskan bahwa baik kotak input dan keluaran milik penerima (sehingga erg dipertahankan), atau, jika mereka milik pengirim, tanda tangan disediakan dan keluaran didukung oleh jumlah erg yang diperlukan jika saldo LETS-nya negatif. Selain itu, ini mengharuskan bahwa saldo erg pengirim tidak dapat dikurangi sampai setidaknya minWithdrawTime jumlah blok telah ditambang setelah erg dikunci.
Dibandingkan dengan LETS yang dikelola, sistem di atas memiliki perbedaan berikut:
- Tidak ada catatan keanggotaan: Tidak seperti LETS yang dikelola, kami tidak menyimpan informasi keanggotaan di sini.
- Kotak ganda: Seseorang dapat membuat beberapa kotak keanggotaan, yang diizinkan. Kami hanya memerlukan bahwa saldo negatif apa pun didukung oleh jumlah erg yang terkunci di dalamnya.
LETS-1: Jumlah Nol, Jaminan
Di atas adalah varian dasar, yang kami sebut LETS-1. Ini memiliki fitur berikut:
- Biaya Pendaftaran Terkunci Waktu: Untuk mencegah serangan spam, seorang anggota harus membayar biaya minimum tertentu dalam erg pada saat bergabung. Biaya ini dapat dikembalikan tetapi hanya setelah sejumlah blok yang telah ditentukan.
- Jumlah Nol: Jumlah saldo LETS dari semua kotak anggota adalah nol. Kotak anggota diperbolehkan memiliki saldo negatif selama masih dalam batas tertentu.
- Jaminan: Untuk keluaran pengirim, erg digunakan sebagai jaminan untuk menutupi saldo LETS negatif pada tarif pertukaran saat ini.
Berikut adalah beberapa variasi dari LETS-1.
LETS-2: Jumlah Nol, Tanpa Jaminan
Ini adalah variasi kecil dari LETS-1 sebagai berikut:
- Biaya pendaftaran yang tidak dapat dikembalikan: Mirip dengan LETS-1, biaya pendaftaran diperlukan untuk mencegah serangan spam. Namun, tidak seperti LETS-1, biaya ini tidak dapat dikembalikan dan harus dikirim ke beberapa komite manajemen yang telah ditentukan.
- Jumlah Nol: Seperti di LETS-1.
LETS-3: Jumlah Positif, Jaminan
Dua varian di atas mengharuskan total saldo LETS selalu nol. Di sini kami mempertimbangkan nilai positif untuk jumlah ini. Secara khusus, varian ini memiliki sifat-sifat berikut:
- Biaya Pendaftaran Terkunci Waktu: Seperti di LETS-1.
- Jumlah Positif: Saldo LETS setiap anggota harus selalu tidak negatif. Ini memastikan bahwa jumlah saldo LETS dari semua kotak anggota adalah positif. Saldo LETS awal ditetapkan pada nilai positif berdasarkan biaya pendaftaran pada tarif saat ini, dibatasi pada nilai maksimum tertentu.
- Jaminan: Setiap pengurangan dalam saldo erg pengirim harus disertai dengan pengurangan saldo LETS yang sesuai pada tarif pertukaran saat ini.
Kami juga dapat mengizinkan penambahan saldo LETS selama transaksi dengan menambahkan jumlah erg yang setara.
LETS-4: Jumlah Positif, Tanpa Jaminan
Ini mirip dengan LETS-3 tetapi dengan beberapa variasi kecil:
- Biaya Pendaftaran yang Tidak Dapat Dikembalikan: Seperti di LETS-2
- Jumlah Positif: Seperti di LETS-3
Tabel berikut merangkum varian-varian tersebut:
| Jumlah Nol | Jumlah Positif | |
|---|---|---|
| Jaminan | LETS-1 | LETS-3 |
| Tanpa jaminan | LETS-2 | LETS-4 |
Kami mempertimbangkan transaksi LETS yang melibatkan satu pasangan pengirim-penerima. Model yang lebih canggih dapat memungkinkan beberapa pengirim dan penerima, dan tidak harus dalam pasangan.
Share post
13 Agustus 2025
9 Juli 2025






