Cara menggunakan crypto untuk menciptakan "barang publik" tanpa risiko bagi investor



Dalam artikel saya akan berbicara tentang apa Kontrak Jaminan, juga dikenal sebagai mekanisme untuk memberikan manfaat publik dan kelompok, dan bersama-sama kita akan menulis implementasi crowdfunding kita sendiri berdasarkan Agen Otonomi pada platform Obyte.

Kontrak Jaminan adalah mekanisme penggalangan dana yang terorganisir untuk menciptakan barang publik baru. Contoh khas dari penggunaan kontrak semacam itu mungkin adalah situasi berikut: para peserta dalam koperasi musim panas memutuskan untuk membangun jalan untuk akses mudah ke pondok musim panas mereka. Untuk melakukan ini, kumpulkan jumlah N dan transfer ke kontraktor untuk membangun jalan. Banyak pertanyaan muncul: di mana menemukan seseorang yang dipercayai semua orang dan membebankan biaya koleksi, bagaimana membuat semua pengguna jalan yang potensial berinvestasi dalam konstruksinya, apa yang akan terjadi jika tidak ada cukup uang yang terkumpul, dll.

Kontrak jaminan sangat mirip dalam arti crowdfunding, hanya investor yang tidak terpapar risiko, seperti halnya dengan investor yang berinvestasi di perusahaan berisiko. Kontrak tersebut, serta crowdfunding, juga dapat memiliki dua hasil - berhasil dan tidak berhasil, tergantung pada pencapaian target untuk jumlah yang dikumpulkan. Hasil dari koleksi yang sukses akan menjadi tanda terima oleh investor, tetapi terkadang tidak hanya oleh mereka, dari barang publik yang baru. Dalam hal kegagalan, uang hanya dikembalikan ke deposan.

Jadi, sebagai permulaan, kami mengulangi kondisi dasar. Inti dari crowdfunding adalah untuk mengumpulkan dana "dalam kerumunan" untuk tujuan yang telah ditentukan, dengan jumlah akhir yang diberikan (tidak harus tetap, bisa dinamis) dan tanggal akhir (juga tidak selalu, tetapi biasanya). Ketika jumlah ini tercapai, putaran pembiayaan dianggap berhasil dan pengumpulan dihentikan, semua dana dialokasikan untuk mencapai tujuan. Dalam hal kegagalan, yaitu, setelah mencapai tenggat waktu dan dengan dana yang tidak mencukupi, semua dana akan dikembalikan ke donor.

Masalah apa yang dipecahkan crowdfunding cryptocurrency? Pertama, itu menyelamatkan investor dari harus percaya dan memverifikasi kepada siapa mereka mengirim uang mereka. Kode agen otonom untuk penggalangan dana terbuka dan setiap investor dapat memastikan bahwa ia dapat menarik kontribusinya setiap saat sampai jumlah akhir tercapai, serta semua dana akan dikirim ke alamat yang dipilih sebelumnya untuk menciptakan barang. Kedua, akuntansi transparan dari semua dana yang dikumpulkan membantu mendistribusikan manfaat di masa depan dari pencapaian tujuan secara proporsional dengan kontribusi yang dibuat.

Masalah lain yang dapat diselesaikan dengan Kontrak Jaminan adalah masalah koordinasi. Hari ini kami akan melengkapi artikel terakhir kami tentang game "Attack 51%" , dan kami hanya akan menyelesaikan masalah ini. Tanpa penggunaan AA, peserta dalam permainan akan berisiko "kurang" dari jumlah yang dikumpulkan karena kurangnya koordinasi. Maka mereka yang sudah berhasil melakukan investasi hanya akan kehilangan uang mereka karena peserta lain yang belum menunjukkan minat, atau tidak punya waktu untuk melakukannya (ingat bahwa tim lawan memiliki tepat 24 jam untuk menantang pemimpin saat ini). Dengan mengumpulkan uang melalui kontrak jaminan, pemain akan dapat menarik uang mereka kapan saja hingga jumlah yang diperlukan dikumpulkan.

Tidak berlaku dalam kasus kami, tetapi fitur lain yang berguna dari kontrak tersebut adalah untuk mengurangi dampak dari "efek pengendara gratis" atau "masalah pengendara gratis". Karena barang publik, yaitu, tidak dapat dicabut atau sulit untuk mengontrol akses ke sana, masalah penunggang bebas adalah yang utama dalam organisasi barang publik. Orang tidak ingin berinvestasi dalam sesuatu yang orang lain dapat gunakan secara gratis, atau investor sendiri, mengikuti perilaku ekonomi yang benar-benar rasional dan memilih strategi "non-investasi", dalam hal koleksi yang sukses, kemungkinan akan dapat menggunakan barang yang dibuat.

Saya juga akan berbicara tentang opsi kontrak jaminan yang dioptimalkan, yang meningkatkan peluang keberhasilan dalam penggalangan dana perilaku rasional para peserta sudah akan menjadi pilihan strategi investasi, daripada mengabaikan.

Kami memainkan game secara kolektif


Sebagai contoh kita, kita akan mengambil game "Serang 51%" yang sudah dikenal di artikel terakhir.
Dalam implementasinya saat ini, peserta game mengirim uang ke alamat AA game. Tetapi algoritme dapat ditingkatkan dan kemungkinan kehilangan uang oleh peserta jika kehilangan tim mereka dapat dikurangi.
Untuk ini, setiap anggota tim dapat mengatur crowdfunding dengan target dinamis yang setara dengan setidaknya 51% dari total kumpulan permainan. Seiring bertambahnya jumlah, target crowdfunding akhir juga akan bergeser. Dan hanya jika berhasil, uang akan dikirim ke alamat permainan AA dan tim akan segera menjadi pemimpin saat ini. Jika acara seperti itu tidak pernah terjadi, maka para peserta tidak akan kehilangan uang mereka, menyia-nyiakan kumpulan permainan dengan sia-sia, tetapi hanya mengambil uang dari crowdfunding AA.

Sumber asli dari kedua agen yang berdiri sendiri selalu tersedia di editor kode Oscript online dalam bentuk template, cukup pilih mereka dari menu drop-down: "51% game serangan" dan "Proksi Penggalangan Dana".

Sebelum Anda mulai menulis AA dalam Oscript, saya sangat merekomendasikan membaca Panduan Memulai (ind) dalam dokumentasi kami untuk segera menjadi akrab dengan prinsip dasar penulisan AA.

Menulis kode


Pertama, kami menulis algoritme: donor mengirim byte ke alamat AA, menerima token crowdfunding dengan rasio 1 banding 1. Kapan saja, ia dapat menukar token ini kembali dengan byte. Setelah menerima byte, AA memeriksa bahwa kami telah mencapai tujuan untuk mengumpulkan dana, dan jika demikian, kemudian mengirim semua byte ke alamat AA game dan menerima token game (token tim) sebagai imbalan. Donatur sekarang dapat menukar token crowdfundingnya dengan token game, yang, di masa depan, jika tim menang, sudah dapat ditukar dengan byte melalui game AA, menerima hingga x2 byte dari yang asli.

Jadi mari kita mulai.

Mulai memproses unit periode penggalangan dana baru. Setelah menerima bidang "mulai" dalam pesan data yang masuk ke alamat AA kami, kami akan mengeluarkan token crowdfunding kami dan menulisnya untuk menyatakan, kami juga akan mengembalikannya sebagai respons kepada penelepon.

{ // start a new fundraising period if: `{trigger.data.start AND !$asset}`, messages: [ { app: 'asset', payload: { is_private: false, is_transferrable: true, auto_destroy: false, fixed_denominations: false, issued_by_definer_only: true, cosigned_by_definer: false, spender_attested: false } }, { app: 'state', state: `{ var[response_unit || '_status'] = 'open'; var['asset'] = response_unit; response['asset'] = response_unit; }` } ] }, 

Memproses setoran dari donor. Pertama, kami menyaring transaksi sampah dengan jumlah yang sangat kecil, yang bahkan tidak cukup untuk komisi. Selanjutnya, periksa kondisi dasar bahwa permainan tidak selesai dan pengumpulan dimungkinkan. Daftar lengkap blok:

 { // contribute if: `{trigger.output[[asset=base]] >= 1e5 AND $asset}`, init: `{ if (var[$destination_aa]['finished']) bounce('game over'); $amount = trigger.output[[asset=base]] - 2000; // to account for fees we need to respond now and to refund bytes or pay shares later $total_raised = var['total_raised'] + $amount; $missing_amount = ceil((balance[$destination_aa][base] + $total_raised)*0.51) - var[$destination_aa]['team_' || $team || '_amount']; $bDone = ($total_raised > $missing_amount); }`, messages: [ { app: 'payment', payload: { asset: "{$asset}", outputs: [{address: "{trigger.address}", amount: "{$amount}"}] } }, { if: `{$bDone}`, app: 'payment', payload: { asset: "base", outputs: [{address: "{$destination_aa}", amount: "{$total_raised}"}] } }, { if: `{$bDone}`, app: 'data', payload: { team: "{$team}" } }, { app: 'state', state: `{ if ($bDone) var[$asset || '_status'] = 'raised'; else var['total_raised'] = $total_raised; }` } ] }, 

Segera setelah pemeriksaan awal, logika utama AA kami berbunyi:

$total_raised = var['total_raised'] + $amount; - di sini kami merangkum jumlah yang baru saja diterima dengan jumlah total dana pada agen.

$missing_amount = ceil((balance[$destination_aa][base] + $total_raised)*0.51) - var[$destination_aa]['team_' || $team || '_amount']; - periksa bahwa jumlah dana baru yang dikumpulkan sudah cukup untuk memenangkan permainan. Perhatikan referensi keseimbangan dan status variabel AA lain: balance[$destination_aa][base] dan var[$destination_aa]['team_' || $team || '_amount'] var[$destination_aa]['team_' || $team || '_amount'] var[$destination_aa]['team_' || $team || '_amount'] .

Kami melakukan semua ini di blok init , yang dipanggil setiap kali sebelum memproses pesan transaksi. Jawaban untuk transaksi yang masuk, jelas, akan mengirimkan token AA dalam rasio satu-ke-satu relatif terhadap byte yang diterima (blok pertama dari array pesan ). Blok kedua dan ketiga akan dieksekusi hanya jika variabel lokal $ bDone disetel ke true (diset pada blok init ). Di dalamnya, kami akan mengirim semua dana dari alamat AA ini ke alamat game AA, menerima token gim pengembalian. Di blok pesan terakhir, kami cukup memperbarui negara, mengatur status yang diperlukan dan jumlah yang dikumpulkan.

Memproses token yang diterima dari game AA, mereka sudah ada di saldo AA kami, kami hanya perlu mengubah status agen:

 { // received team asset if: `{trigger.output[[asset=var[$destination_aa]['team_' || $team || '_asset']]] AND $asset}`, messages: [ { app: 'state', state: `{ var[$asset || '_status'] = 'done'; var['asset'] = false; var['total_raised'] = false; }` } ] }, 

Pengembalian investasi oleh pemain. Kami mengizinkan Anda untuk menolak berpartisipasi kapan saja dan mengambil byte Anda kembali. Untuk melakukan ini, pemain mengirim token AA ini, dan kami mengiriminya byte yang sama sebagai transaksi balasan:

 { // refund if: `{$asset AND trigger.output[[asset=$asset]] > 0}`, init: `{ $amount = trigger.output[[asset=$asset]]; }`, messages: [ { app: 'payment', payload: { asset: "base", outputs: [{address: "{trigger.address}", amount: "{$amount}"}] } }, { app: 'state', state: `{ var['total_raised'] -= $amount; }` } ] }, 

Tukar token AA kami dengan token game. Kami cukup mengirim token game yang ada di saldo AA kami (dalam hal melewati blok if) dalam jumlah yang sama dengan jumlah token "kami" yang diterima.

 { // pay the obtained team asset in exchange for the issued asset if: `{ $in_asset = trigger.output[[asset!=base]].asset; var[$in_asset || '_status'] == 'done' }`, messages: [ { app: 'payment', payload: { asset: "{var[$destination_aa]['team_' || $team || '_asset']}", outputs: [{address: "{trigger.address}", amount: "{trigger.output[[asset=$in_asset]]}"}] } }, ] } 

Kode agen siap, berikut daftar lengkapnya:

Kode agen lengkap
 { /* This is a fundraising proxy AA. It allows to raise money up to a specific target. If the target is reached, the money is forwarded to another AA, otherwise the money is refunded. This specific example raises money for challenging the current candidate winner in 51% attack game. The target is a moving target as other teams may be adding contributions at the same time. Contributors get shares of the proxy in exchange for Bytes. They can exchange the shares back to the same amount of Bytes any time before the target is reached. As soon as the target is reached, the raised funds are forwarded to the game and the proxy receives the shares of the team in exchange. Then, the contributors can exchange the shares of the proxy for the shares of the team. */ init: `{ $asset = var['asset']; $destination_aa = 'WWHEN5NDHBI2UF4CLJ7LQ7VAW2QELMD7'; $team = 'VF5UVKDSOXPMITMDGYXEIGUJSQBRAMMN'; }`, messages: { cases: [ { // start a new fundraising period if: `{trigger.data.start AND !$asset}`, messages: [ { app: 'asset', payload: { is_private: false, is_transferrable: true, auto_destroy: false, fixed_denominations: false, issued_by_definer_only: true, cosigned_by_definer: false, spender_attested: false } }, { app: 'state', state: `{ var[response_unit || '_status'] = 'open'; var['asset'] = response_unit; response['asset'] = response_unit; }` } ] }, { // contribute if: `{trigger.output[[asset=base]] >= 1e5 AND $asset}`, init: `{ if (var[$destination_aa]['finished']) bounce('game over'); $amount = trigger.output[[asset=base]] - 2000; // to account for fees we need to respond now and to refund bytes or pay shares later $total_raised = var['total_raised'] + $amount; $missing_amount = ceil((balance[$destination_aa][base] + $total_raised)*0.51) - var[$destination_aa]['team_' || $team || '_amount']; $bDone = ($total_raised > $missing_amount); }`, messages: [ { app: 'payment', payload: { asset: "{$asset}", outputs: [{address: "{trigger.address}", amount: "{$amount}"}] } }, { if: `{$bDone}`, app: 'payment', payload: { asset: "base", outputs: [{address: "{$destination_aa}", amount: "{$total_raised}"}] } }, { if: `{$bDone}`, app: 'data', payload: { team: "{$team}" } }, { app: 'state', state: `{ if ($bDone) var[$asset || '_status'] = 'raised'; else var['total_raised'] = $total_raised; }` } ] }, { // received team asset if: `{trigger.output[[asset=var[$destination_aa]['team_' || $team || '_asset']]] AND $asset}`, messages: [ { app: 'state', state: `{ var[$asset || '_status'] = 'done'; var['asset'] = false; var['total_raised'] = false; }` } ] }, { // refund if: `{$asset AND trigger.output[[asset=$asset]] > 0}`, init: `{ $amount = trigger.output[[asset=$asset]]; }`, messages: [ { app: 'payment', payload: { asset: "base", outputs: [{address: "{trigger.address}", amount: "{$amount}"}] } }, { app: 'state', state: `{ var['total_raised'] -= $amount; }` } ] }, { // pay the obtained team asset in exchange for the issued asset if: `{ $in_asset = trigger.output[[asset!=base]].asset; var[$in_asset || '_status'] == 'done' }`, messages: [ { app: 'payment', payload: { asset: "{var[$destination_aa]['team_' || $team || '_asset']}", outputs: [{address: "{trigger.address}", amount: "{trigger.output[[asset=$in_asset]]}"}] } }, ] } ] } } 


Kami tidak menerapkan algoritma paling sepele, karena target kami adalah dinamis, yang tidak khas dari kontrak jaminan tipikal. Di dalamnya, paling sering jumlah target tetap, serta waktu tenggat. Ini tidak akan memerlukan perubahan besar dalam kode, jadi mari kita tinggalkan ini sebagai latihan untuk pembaca.

Strategi terbaik adalah berinvestasi!


Dan sekarang kembali ke masalah free rider. Dalam hal permainan, kami tidak memiliki masalah seperti itu, karena hanya pemegang token crowdfunding yang bisa menang. Tetapi memecahkan masalah penunggang bebas akan membantu dalam kasus permainan. Kita dapat "merangsang" orang untuk berinvestasi. Untuk melakukan ini, penyelenggara penggalangan dana, yang juga pencipta AA, dapat memberikan kompensasi kecil, yang akan ia bayarkan dari sakunya jika tujuan pengumpulan tidak tercapai. Dalam hal koleksi yang berhasil, penyelenggara akan mengambil persentase kecil. Artinya, kami memperkenalkan pihak ketiga yang, untuk memperoleh manfaat, akan menanggung risiko pengumpulan yang gagal.

Menerapkan “crowdfunding yang dioptimalkan” seperti itu, perilaku “non-investasi” yang sebelumnya rasional (secara umum, agar barang publik apa pun menjadi penunggang bebas selalu merupakan strategi yang paling menguntungkan secara ekonomi) mungkin menjadi kurang rasional daripada berinvestasi. Ini mungkin sangat relevan dalam kasus pembuatan barang kelompok di mana lingkaran orang tertentu terlibat. Ini tidak sepenuhnya menghilangkan masalah penumpang gelap, tetapi menjadikan partisipasi sebagai perilaku rasional.

Kode yang mengimplementasikan "kontrak jaminan yang dioptimalkan" juga akan dibiarkan sebagai latihan yang menarik bagi mereka yang menginginkannya.

Source: https://habr.com/ru/post/id475100/


All Articles