Pernahkah Anda berpikir tentang bagaimana uang diciptakan? Biasanya, itu dibuat dari ketiadaan oleh bank. Ketika seseorang mengambil pinjaman, bank menambahkan uang pinjaman tersebut ke jumlah yang sudah tercatat dalam database rekening banknya. Jadi jika $100 sudah ada dalam entri database untuk rekening bank dan seseorang mengambil pinjaman sebesar $10.000, bank akan menulis ulang konten entri tersebut menjadi $10.100. Jadi, bank meminjamkan uang yang tidak dimilikinya. Tentu saja pinjaman itu harus dilunasi.

Ketika pinjaman dilunasi, uang yang dihasilkan oleh pinjaman tersebut hilang. Jadi uang ini muncul dari ketiadaan dan menghilang menjadi ketiadaan (jangan membahas topik yang menarik, yang akan sedikit memperumit masalah). Dengan demikian, uang ini hanya ada sementara. Ada perumpamaan tentang arti uang yang hanya ada sementara.

Seorang koboi masuk ke bar. Setelah minum beberapa kali, penjaga bar bertanya apakah dia mau meminjamkan $10 untuk memperbaiki lubang di atap. Koboi itu setuju untuk meminjamkan $10 tersebut, dengan syarat akan dibayar kembali dalam seminggu. Penjaga bar memanggil tukang atap, yang memperbaiki atap, dan penjaga bar membayar $10. Sementara itu, sepatu tukang atap rusak, dan dia pergi ke tukang sepatu untuk membeli yang baru seharga $10 lagi. Tukang sepatu senang dengan rejeki nomplok yang tak terduga dan dengan cepat uangnya dibelanjakan di bar yang sama. $10 kemudian dikembalikan ke penjaga bar.

Ketika seminggu berlalu, si koboi kembali, dan penjaga bar mengembalikan $10. Koboi itu berterima kasih padanya, mengeluarkan korek api, dan membakar uangnya. Penjaga bar, dengan mata terbelalak, bertanya, ‘Mengapa kamu melakukan itu?’, dan si koboi menjawab, ‘Itu uang palsu; itu tidak ada gunanya.’

Dalam perumpamaan tersebut, koboi itu seperti bank. Dia meminjamkan uang yang tidak dia miliki. Dia menciptakan uang ini begitu saja, dan uang itu lenyap seperti pinjaman bank ketika dibakar. Namun demikian, bar tersebut mendapatkan atap baru dari uang sementara ini, tukang atap menerima sepasang sepatu baru, dan tukang sepatu mempunyai cukup uang untuk membeli beberapa minuman. Ini adalah hasil nyata dari uang yang hanya ada sementara. Jadi yang kita pakai sebagai uang tidak lebih dari hutang seseorang. Uang adalah hutang!

Nilai uang pada akhirnya didasarkan pada suatu bentuk kepercayaan. Kita percaya bahwa orang lain juga menghargainya, jadi ketika kita melakukan sesuatu untuk seseorang sebagai imbalan, kita menerima uang karena kita percaya bahwa uang itu akan diterima ketika kita memerlukan sesuatu sebagai imbalan. Kepercayaan ini menjadikan uang sebagai alat tukar universal.

Contoh bagusnya adalah Bitcoin. Saldo Bitcoin kami tidak lebih dari sebuah entri dalam buku besar yang didistribusikan. Tidak ada yang mendukung hal ini, namun orang-orang di seluruh dunia bersedia membayar uang sungguhan untuk Bitcoin. Oleh karena itu, nilai Bitcoin adalah murni masalah kepercayaan. Uang adalah kepercayaan!

Inilah ide dasar yang mengilhami konsep uang karma. Bagaimana jika semua orang beroperasi seperti bank? Daripada mengambil uang secara kredit, mereka malah menciptakannya sendiri. Tentu saja, sistem seperti itu hanya akan berfungsi jika ada batasan jumlah uang yang dapat diciptakan. Jadi utang setiap orang akan diketahui publik.

Jika saya harus memilih kepada siapa saya akan menjual produk atau jasa saya, saya akan memberikannya kepada orang yang utangnya paling sedikit, karena ini memberikan peluang terbaik agar barang atau jasa tersebut dapat dilunasi dengan cepat. Oleh karena itu, setiap orang tertarik untuk menjaga utangnya tetap rendah dengan melunasinya.

Mari kita lihat bagaimana perumpamaan koboi akan terlihat dalam sistem ini. Tidak diperlukan seorang koboi (bank), karena penjaga bar dapat menghasilkan $10 untuk tukang atap itu sendiri. Hal ini menciptakan utang $10 bagi penjaga bar yang terlihat oleh semua orang, namun sebagai imbalannya, atapnya diperbaiki. Tukang atap meneruskan $10 ini kepada tukang sepatu, dan ketika tukang sepatu mengembalikannya kepada penjaga bar, $10 itu musnah bersama dengan hutang penjaga bar. Dengan demikian, utang penjaga bar kembali menjadi nol.

Dengan demikian, proses penciptaan uang sementara dapat berjalan dengan baik bahkan tanpa bank. Yang diperlukan hanyalah agar tukang atap memercayai uang yang diciptakan oleh penjaga bar dan yakin bahwa uang tersebut sama baiknya dengan uang $10 yang diciptakan oleh bank.

Saya telah merealisasikan uang karma ini di Ethereum Blockchain dengan kontrak pintar Solidity yang sederhana. Implementasi karma saya adalah kontrak ERC20, yang sangat bagus karena dapat dengan mudah digunakan dengan dompet Ethereum apa pun. Keunikan karma adalah, sementara dalam kasus mata uang lain kita membelanjakannya dari saldo kita, di sini, saldo kita dimulai dari nol dan meningkat seiring dengan setiap pembelanjaan (penciptaan uang). Semakin besar saldo kita, maka kita akan semakin banyak berhutang, jadi disini tujuannya adalah untuk mengurangi saldo kita.

Mari kita lihat contoh singkatnya. Alice ingin membeli apel dari John, jadi dia membayar John sepuluh dolar karma untuk apel tersebut. Saldo Alice meningkat menjadi $10. Kemudian, John membeli jeruk dari Alice, jadi ketika dia membayar $10 kepada Alice, utangnya telah dilunasi, dan saldo Alice berkurang kembali menjadi $0.

Setelah teorinya, mari kita lihat kodenya (tersedia di sini di GitHub):

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

contract Karma is IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _debts;
    mapping(address => mapping(address => uint256)) private _allowances;

    string private _name;
    string private _symbol;
    uint private _cycleReward;

    constructor(string memory name_, string memory symbol_, uint cycleReward) {
        _name = name_;
        _symbol = symbol_;
        _cycleReward = cycleReward;
    }

    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    // totalSupply is meaningless
    function totalSupply() public view virtual override returns (uint256) {
        return 0;
    }

    function balanceOf(
        address account
    ) public view virtual override returns (uint256) {
        return _balances[account];
    }

    function debtOf(
        address debtor,
        address creditor
    ) public view virtual returns (uint256) {
        return _debts[debtor][creditor];
    }

    function transfer(
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(msg.sender, to, amount);
        return true;
    }

    function allowance(
        address owner,
        address spender
    ) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(
        address spender,
        uint256 amount
    ) public virtual override returns (bool) {
        require(spender != address(0), "ERC20: approve to the zero address");

        address owner = msg.sender;
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        _spendAllowance(from, msg.sender, amount);
        _transfer(from, to, amount);
        return true;
    }

    function mineCycle(
        address[] memory nodes,
        uint256 amount
    ) public virtual returns (bool) {
        // checking debts in cycle from 0..n
        for (uint i = 0; i < nodes.length - 1; i++) {
            require(
                _debts[nodes[i]][nodes[i + 1]] >= amount,
                "Karma: Not enough debt for the cycle"
            );
        }

        // checking the last debt (end of cycle)
        require(
            _debts[nodes[nodes.length - 1]][nodes[0]] >= amount,
            "Karma: Not enough debt for the cycle"
        );

        // decreasing the debts and balances and pay cyleReward
        for (uint i = 0; i < nodes.length - 1; i++) {
            _debts[nodes[i]][nodes[i + 1]] -= amount;
            _balances[nodes[i]] -= amount;
            _transfer(nodes[i], msg.sender, _cycleReward);
        }

        _debts[nodes[nodes.length - 1]][nodes[0]] -= amount;
        _balances[nodes[nodes.length - 1]] -= amount;
        _transfer(nodes[nodes.length - 1], msg.sender, _cycleReward);

        return true;
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(to != address(0), "ERC20: transfer to the zero address");

        _balances[from] += amount;
        _debts[from][to] += amount;

        emit Transfer(from, to, amount);
    }

    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(
                currentAllowance >= amount,
                "ERC20: insufficient allowance"
            );

            uint256 newAmount = currentAllowance - amount;
            _allowances[owner][spender] = newAmount;
            emit Approval(owner, spender, newAmount);
        }
    }
}

Seperti yang bisa dilihat, ini adalah token ERC20 yang sepenuhnya standar. Di konstruktor, kita dapat menentukan nama token dan simbol serta parameter yang disebut cycleReward, yang akan kita bahas nanti. Karma dapat mewakili dolar, euro, uang apa pun, tetapi juga waktu (misalnya, saya akan bekerja untuk Anda selama satu jam dengan imbalan satu jam kerja) atau apa pun. Jadi karma adalah sistem peminjaman yang umum.

Metode balanceOf standar ERC20 adalah untuk menanyakan saldo individu. Penting agar setiap orang hanya ditautkan ke satu alamat Ethereum. Jika tidak demikian, maka jika seseorang berhutang banyak, mereka akan membuka rekening baru, sehingga seluruh sistem tidak ada gunanya. Untungnya, ada solusi seperti Bukti Kemanusiaan atau WorldCoin, yang dapat memastikan bahwa setiap individu memiliki alamat unik.

Saya juga memperkenalkan fungsi debtOf, yang secara tepat dapat menanyakan siapa yang berhutang berapa banyak poin kepada siapa.

Fungsi standar transfer digunakan untuk memindahkan keseimbangan. Di satu sisi, hal ini meningkatkan saldo pengguna; di sisi lain, ia mencatat utang kepada pihak penerima. Oleh karena itu, jika Alice membayar John $10, saldo Alice akan bertambah sebesar $10, dan akan dicatat bahwa Alice berhutang pada John $10.

Tampaknya kode tersebut tidak melakukan apa yang saya jelaskan sebelumnya. Misalnya, jika John sekarang membayar Alice $10, alih-alih Alice dan John memiliki saldo $0, saldo Alice akan tetap di $10, dan saldo John juga akan menjadi $10. Selain itu, dalam matriks hutang, Alice sekarang berhutang pada John $10, dan John akan berhutang pada Alice $10. Mengapa kontrak pintar tidak menyelesaikan utang-utang ini?

Kasus Alice dan John sangat jelas, namun biasanya, rantai utangnya jauh lebih rumit. Dalam contoh koboi, ada tiga orang di sepanjang rantai. Namun, bisa saja sebuah rantai berisi sepuluh orang atau lebih. Menemukan rantai seperti itu bukanlah hal yang sepele. Inilah mengapa penambang karma dibutuhkan.

Para penambang karma terus-menerus mengamati grafik utang; jika mereka menemukan sebuah siklus, mereka dapat mengirimkannya ke kontrak pintar. Inilah gunanya metode mineCycle. Metode ini memeriksa rantai yang dikirimkan; jika valid maka akan dilakukan modifikasi saldo. Untuk ini, penambang akan menerima karma kecil dari setiap anggota rantai karena mengurangi saldo mereka (jumlah hadiah ditentukan oleh cycleReward).

Jadi, penambangan karma hampir sama persis dengan penambangan Bitcoin. Anggota menjalankan program di mesinnya, mengonsumsi listrik dan daya komputasi (menemukan siklus dalam grafik), menghasilkan karma sebagai imbalannya.

Masih ada beberapa metode terkait standar ERC20, namun ini tidak menarik dari sudut pandang sistem.

Karma dapat menjadi solusi ideal bagi masyarakat yang mencari alternatif sistem uang tradisional. Namun anggota sistem seperti itu juga bisa berupa perusahaan atau proyek. Misalnya, sebuah proyek sumber terbuka dapat menerima sumbangan dan membayar pengembang dalam bentuk karma, yang kemudian dapat menukarkannya dengan, misalnya, sayuran dan buah-buahan yang ditanam secara lokal di komunitas yang menggunakan karma.

Tentu saja, tidak ada kerangka hukum yang mendukung karma seperti yang terjadi pada uang sungguhan, namun Bitcoin telah menunjukkan bahwa suatu mata uang dapat bekerja murni berdasarkan kepercayaan — tanpa dukungan apa pun. Dibandingkan dengan Bitcoin, karma tidak memerlukan daya komputasi yang besar, juga tidak memerlukan konsumsi energi suatu negara. Sistem ini bergantung pada kepercayaan, dan identitas kita mendukung uang.