Вы когда-нибудь задумывались о том, как создаются деньги? Ну, как правило, банки делают его из ничего. Когда кто-то берет кредит, банк добавляет заемные деньги к сумме, уже записанной в его базе данных по банковскому счету. Таким образом, если 100 долларов США уже присутствовали в записи базы данных для банковского счета и кто-то берет кредит в размере 10 000 долларов США, банк перепишет содержимое записи на 10 100 долларов США. Таким образом, банк выдает в долг деньги, которых у него нет. Разумеется, кредит необходимо погасить.

Когда кредит погашен, деньги, созданные кредитом, исчезают. Вот и эти деньги возникают из ничего и исчезают в ничто (не будем вдаваться в интересующую нас тему, которая несколько усложняет дело). Таким образом, эти деньги существуют лишь временно. Есть притча о деньгах, которые существуют лишь временно.

Ковбой заходит в бар. После нескольких выпивок бармен спрашивает его, одолжит ли он ему 10 долларов, чтобы заделать дыру в крыше. Ковбой соглашается одолжить 10 долларов с условием, что они будут возвращены через неделю. Бармен вызывает кровельщика, который чинит крышу, и бармен платит 10 долларов. Тем временем у кровельщика разваливается башмак, и он идет к сапожнику, чтобы купить новый еще за 10 долларов. Сапожник обрадован неожиданной удачей и быстро тратит деньги в том же баре. Таким образом, 10 долларов возвращаются бармену.

Через неделю ковбой возвращается, а бармен возвращает 10 долларов. Ковбой благодарит его, вытаскивает спичку и сжигает деньги. Бармен с широко раскрытыми глазами спрашивает: «Зачем ты это сделал?», на что ковбой отвечает: «Это фальшивые деньги; это ничего не стоит».

В притче ковбой подобен банку. Он дает взаймы деньги, которых у него нет. Он создает эти деньги из воздуха, и они исчезают, как банковские кредиты, когда их сжигают. Тем не менее на эти временные деньги бар получил новую крышу, кровельщик получил новую пару обуви, а у сапожника хватило денег, чтобы выпить несколько стаканчиков. Это ощутимые результаты денег, которые существуют лишь временно. Итак, то, что мы используем в качестве денег, — это не что иное, как чей-то долг. Деньги – это долг!

Ценность денег в конечном итоге основана на форме доверия. Мы верим, что другие тоже это ценят, поэтому, когда мы делаем что-то для кого-то взамен, мы принимаем деньги, потому что верим, что они будут приняты, когда мы потребуем что-то взамен. Это доверие делает деньги универсальным средством обмена.

Хорошим примером этого является Биткойн. Наш биткойн-баланс — это не что иное, как запись в распределенном реестре. Это ничем не подкреплено, однако люди во всем мире готовы платить за Биткойн реальные деньги. Таким образом, ценность Биткойна — это исключительно вопрос доверия. Деньги – это доверие!

Это были основные идеи, которые легли в основу концепции кармических денег. Что, если бы все работали как банк? Вместо того, чтобы брать деньги в кредит, они создавали бы их сами. Конечно, такая система работала бы только в том случае, если бы существовал предел количества денег, которые можно было создать. Таким образом, долг каждого будет государственным.

Если бы мне пришлось выбирать, кому продавать мои продукты или услуги, я бы отдал их тому, у кого наименьшая задолженность, поскольку это дает наилучшие шансы на быструю выплату долга. Поэтому каждый заинтересован в сохранении своего долга на низком уровне путем его погашения.

Давайте посмотрим, как бы выглядела ковбойская притча в этой системе. Нет необходимости в ковбое (банке), поскольку бармен сам может заработать 10 долларов для кровельщика. Это создает долг в 10 долларов для видимого всем бармена, но взамен ему починят крышу. Кровельщик передает эти 10 долларов сапожнику, а когда сапожник передает их обратно бармену, эти 10 долларов уничтожаются вместе с долгом бармена. Таким образом, долг бармена снова равен нулю.

Таким образом, процесс создания переходных денег хорошо работает даже без банков. Все, что нужно кровельщику, — это довериться деньгам, созданным барменом, и поверить, что это такие же хорошие деньги, как и 10 долларов, созданные банком.

Я реализовал эти деньги кармы на блокчейне Ethereum с помощью простого смарт-контракта Solidity. Моя реализация кармы — это контракт ERC20, и это здорово, потому что его можно легко использовать с любым кошельком Ethereum. Особенность кармы в том, что если в случае с другими валютами мы тратим со своего баланса, то здесь наш баланс начинается с нуля и увеличивается с каждой тратой (созданием денег). Чем больше наш баланс, тем больше мы в долгу, поэтому здесь цель состоит в том, чтобы уменьшить наш баланс.

Давайте рассмотрим краткий пример. Алиса хочет купить яблоки у Джона, поэтому она платит Джону десять долларов кармы за яблоки. Таким образом, баланс Алисы увеличивается до 10 долларов. Позже Джон покупает апельсины у Алисы, поэтому, когда он платит Алисе 10 долларов, долг погашается, и баланс Алисы уменьшается до 0 долларов.

После теории давайте взглянем на код (доступен здесь на 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);
        }
    }
}

Как видно, это совершенно стандартный токен ERC20. В конструкторе мы можем указать имя и символ токена, а также параметр cycleReward, о котором мы поговорим позже. Карма может представлять собой доллары, евро, любые деньги, а также время (например, я буду работать на вас один час в обмен на один час работы) или что-то еще. Итак, карма — это общая система кредитования.

Метод balanceOf стандарта ERC20 предназначен для запроса баланса любого человека. Важно, чтобы каждый человек был привязан только к одному адресу Ethereum. Если бы это было не так, то если бы кто-то сильно задолжал, он бы просто открыл новый счет, и вся система была бы бессмысленной. К счастью, существуют такие решения, как Proof of Humanity или WorldCoin, которые могут гарантировать, что у каждого человека будет уникальный адрес.

Я также представил функцию debtOf, которая может точно запрашивать, кто кому сколько баллов должен.

Для перемещения баланса используется стандартная функция transfer. С одной стороны, это увеличивает баланс пользователя; с другой стороны, он записывает задолженность перед принимающей стороной. Следовательно, если Алиса заплатит Джону 10 долларов, баланс Алисы увеличится на 10 долларов, и будет отмечено, что Алиса должна Джону 10 долларов.

Может показаться, что код не делает то, что я описал ранее. Например, если Джон теперь заплатит Алисе 10 долларов, а баланс Алисы и Джона будет равен 0 долларов, баланс Алисы останется на уровне 10 долларов, а баланс Джона также станет 10 долларов. Кроме того, в матрице долга Алиса теперь должна Джону 10 долларов, а Джон будет должен Алисе 10 долларов. Почему смарт-контракт не решает эти долги?

Случай Алисы и Джона очень прост, но обычно образуются гораздо более сложные долговые цепочки. В примере с ковбоем в цепи было три человека. Однако вполне возможно, что в цепочке будет десять и более человек. Найти такие цепочки отнюдь не тривиально. Вот почему нужны майнеры кармы.

Майнеры кармы постоянно следят за графиком долга; если они обнаружат цикл, они смогут отправить его в смарт-контракт. Для этого и нужен метод mineCycle. Метод проверяет отправленную цепочку; если он действителен, он выполнит изменения в балансах. За это майнер будет получать небольшую карму от каждого участника цепочки за уменьшение их балансов (размер вознаграждения определяется цифрой cycleReward).

Таким образом, майнинг кармы практически ничем не отличается от майнинга биткойнов. Участник запускает программу на своей машине, потребляя электроэнергию и вычислительную мощность (находя циклы на графике), производя взамен карму.

Есть еще несколько методов, связанных со стандартом ERC20, но они не представляют интереса с системной точки зрения.

Карма может стать идеальным решением для сообществ, ищущих альтернативу традиционной денежной системе. Но участниками такой системы также могут быть компании или проекты. Например, проект с открытым исходным кодом может принимать пожертвования и платить разработчикам в виде кармы, которые затем могут обменивать их, скажем, на местные овощи и фрукты, выращенные в сообществе, используя карму.

Конечно, не существует правовой базы, поддерживающей карму, как в случае с реальными деньгами, но Биткойн показал, что валюта может работать исключительно на доверии — без какой-либо поддержки. По сравнению с Биткойном, карма не требует огромных вычислительных мощностей и не требует потребления энергии в стране. Система опирается на доверие, а наша личность обеспечивает деньги.