Руководство по интеграции Minter в бизнес
5 лет назад 0
Техническая часть
4 июня команда блокчейн-проекта Минтер запустила программу информационной поддержки для желающих использовать сеть Minter в своем бизнесе. С тех пор поступило немало вопросов касательно интеграции BIP и кастомных монет, созданных пользователями (в нашем случае — бизнесменами и предпринимателями). Сами вопросы можно разделить на две категории: как осуществить внедрение на техническом уровне и как сделать это в соответствии с действующим законодательством.
Данное руководство состоит из двух частей. Первая отвечает на вопрос имплементации с технической точки зрения. Во второй рассматриваются правовые аспекты использования сети Minter в бизнесе на основе присланных вами кейсов.
Сначала необходимо определить, в каком контексте вы будете взаимодействовать с сетью Minter. Есть две опции: использование BIP, нативной цифровой монеты сети, или же своей собственной, созданной «под ключ» и соответствующей конкретно вашей бизнес-модели.
Чтобы создать свою монету, вам необходимо иметь определенное количество BIP на балансе (комиссия за тикер, первичный объем резервирования). У пользователей, участвовавших в кампании раннего доступа, они уже имеются; если же вы в проекте относительно недавно, единственный вариант приобрести BIP — через MBank. Вы также можете начать принимать оплату в BIP уже сейчас, чтобы иметь необходимое количество монет в будущем.
Прежде чем перейти к кейсам имплементации, необходимо отметить, что вам потребуется программист (если вы сами им не являетесь). Информация, представленная ниже, носит сугубо технический характер, поэтому вам будет нужно либо нанять специалиста, либо обратиться к сотруднику, который уже работает в вашем штате (если такой, разумеется, есть). Рассмотрим варианты на примере использования PHP SDK:
Кейс №1: Прием BIP/вашей монеты в качестве оплаты за товары и услуги
- Пользователь заходит в карточку товара, нажимает кнопку «Оплатить товар за BIP».
- Продавец должен определить курс BIP (или же кастомной монеты) за определенный товар или услугу. Например, 1 пинта пива = 12 BIP.
$price = 12; // BIP
В случае использования своей монеты вам необходимо всего лишь указать ее тикер вместо BIP.
3. Система генерирует адрес в сети Minter. Для этого используем метод MinterWallet::create(). Данный метод возвращает массив с данными адреса: сид, мнемоническая фраза, приватный ключ, адрес. Сохраняем приватный ключ и адрес в базу и показываем адрес пользователю, чтобы он перечислил на него необходимую сумму.
use Minter\SDK\MinterWallet;$wallet = MinterWallet::create();$address = $wallet[‘address’];$privateKey = $wallet[‘private_key’];
4. Система проверяет оплату. Вариант реализации:
a. Запрашивать баланс созданного адреса в течение 20 минут каждые 30 секунд. Как только на балансе появляется необходимая сумма, считаем, что оплата произведена. Если за 20 минут платеж не поступил, останавливаем проверку баланса и считаем оплату отмененной.
b. Для этого используем MinterAPI.
use Minter\MinterAPI;$api = new MinterAPI(‘https://minter-node-1.testnet.minter.network:8841′);$response = $api->getBalance($address);$balance = $response->result->balance->BIP;if ($balance >= $price) {// success payment}
Кейс №2: Выплата кэшбека в вашей монете
- Предположим, у нас есть адрес, в котором мы создали монеты BONUS, и его приватный ключ.
$marketAddress = ‘Mx31e61a05adbd13c6b625262704bc305bf7725026’;$marketPrivateKey = ‘07bc17abdcee8b971bb8723e36fe9d2523306d5ab2d683631693238e0f9df142’;
2. Необходимо установить Minter PHP SDK.
composer require minter/minter-php-sdk
3. При регистрации пользователя в магазине создаем ему адрес в сети Minter. Для этого используем метод MinterWallet::create(). Он возвращает массив с данными адреса: сид, мнемоническая фраза, приватный ключ, адрес. Сохраняем приватный ключ и адрес в базу.
use Minter\SDK\MinterWallet;$wallet = MinterWallet::create();$userAddress = $wallet[‘address’];$userPrivateKey = $wallet[‘private_key’];
4. После оплаты товара пользователем начисляем ему монеты BONUS. Для этого необходимо создать транзакцию и отправить ее в сеть Minter.
5. Сначала инициализируем класс MinterAPI. Для этого можем использовать любую открытую ноду.
use Minter\MinterAPI;$nodeUrl = ‘https://minter-node-1.testnet.minter.network:8841′; // example of a node url$api = new MinterAPI($nodeUrl);
6. Далее необходимо создать транзакцию типа Send.
Получаем nonce для адреса, на котором хранятся монеты BONUS.
$nonce = $api->getNonce($marketAddress);
Допустим, мы хотим отправить 10 монет BONUS.
$amount = 10;
Создаем транзакцию:
use Minter\SDK\MinterTx;use Minter\SDK\MinterCoins\MinterSendCoinTx;$tx = new MinterTx([‘nonce’ => $nonce,‘chainId’ => MinterTx::MAINNET_CHAIN_ID,‘gasPrice’ => 1,‘gasCoin’ => ‘BIP’,‘type’ => MinterSendCoinTx::TYPE,‘data’ => [‘coin’ => ‘BONUS’,‘to’ => $userAddress,‘value’ => $amount],‘payload’ => ‘’,‘serviceData’ => ‘’,‘signatureType’ => MinterTx::SIGNATURE_SINGLE_TYPE]);
Подписываем транзакцию приватным ключом (от адреса, на котором хранятся монеты BONUS).
$transaction = $tx->sign($marketPrivateKey);
7. Отправляем подписанную транзакцию в сеть.
use GuzzleHttp\Exception\RequestException;try { $response = $api->send($transaction);} catch(RequestException $exception) {// short exception message$message = $exception->getMessage();// error response in json$content = $exception->getResponse()->getBody()->getContents();// error response as array$error = json_decode($content, true);}
Кейс №3: Доступ к ресурсам
- Предположим, у нас есть адрес, в котором мы создали монеты VIP, и его приватный ключ.
$mainAddress = ‘Mx31e61a05adbd13c6b625262704bc305bf7725026’;$mainAddressPrivateKey = ‘07bc17abdcee8b971bb8723e36fe9d2523306d5ab2d683631693238e0f9df142’;
2. Теперь мы хотим ограничить доступ к нашей системе. Чтобы получить доступ к системе или определенному действию, пользователю необходимо отправить N количество VIP. Для этого генерируем специальный адрес, на который пользователь перечислит монеты VIP для получения доступа (или приглашения).
use Minter\SDK\MinterWallet;$wallet = MinterWallet::create();$address = $wallet[‘address’];$privateKey = $wallet[‘private_key’];
3. Определяем количество VIP, необходимое для доступа к системе.
$requiredCoinAmount = 5;
4. Проверяем, что пользователь перевел монеты. Для этого мы можем проверять баланс сгенерированного адреса каждые 15 секунд в течение 20 минут.
use Minter\MinterAPI;$api = new MinterAPI(‘https://minter-nodes-1.mainnet.minter.network:8841′);$response = $api->getBalance($address);$balance = $response->result->balance;if (isset($balance->VIP) && $balance >= $requiredCoinAmount) {// open access to the system}
5. Также мы можем разослать монеты тем пользователям, которым хотим дать доступ к системе.
Предположим, у нас есть массив со следующими адресами:
$addresses = [‘Mx0a2bbda12c7b4660930d8a4d05b4c4d66abed1fc’,‘Mx6041bb9afa46eea000129fb4a7ad56fa770c549c’,‘Mx6af840f4108c6ba127301b9f631052d501c4c221’];
Далее мы можем отправить монеты одной транзакцией сразу на несколько адресов.
use Minter\SDK\MinterTx;use Minter\SDK\MinterCoins\MinterMultiSendTx;$data = [];for($addresses as $address) {$data[] = [‘coin’ => ‘VIP’,‘to’ => $address,‘value’ => ‘10’];}$tx = new MinterTx([‘nonce’ => $api->getNonce($mainAddress),‘chainId’ => MinterTx::MAINNET_CHAIN_ID,‘gasPrice’ => 1,‘gasCoin’ => ‘BIP’,‘type’ => MinterMultiSendTx::TYPE,‘data’ => [‘list’ => $data],‘payload’ => ‘’,‘serviceData’ => ‘’,‘signatureType’ => MinterTx::SIGNATURE_SINGLE_TYPE]);$transaction = $tx->sign($mainAddressPrivateKey)
6. Отправляем подписанную транзакцию в сеть.
use GuzzleHttp\Exception\RequestException;try { $response = $api->send($transaction);} catch(RequestException $exception) {// short exception message$message = $exception->getMessage();// error response in json$content = $exception->getResponse()->getBody()->getContents();// error response as array$error = json_decode($content, true);}
Кейс №4: Рейтинг пользователей
- Предположим, пользователь регистрируется на сайте. Мы создаем ему новый адрес и сохраняем в базу данных.
use Minter\SDK\MinterWallet;$wallet = MinterWallet::create();$userAddress = $wallet[‘address’];$userPrivateKey = $wallet[‘private_key’];
2. За определенные действия на сайте начисляем ему монеты (баллы). Для этого необходимо сформировать и отправить транзакцию типа Send.
Получаем nonce для адреса, на котором хранятся наши монеты (например, RATING).
$nonce = $api->getNonce($mainAddress);
Допустим, мы хотим отправить 10 монет RATING.
$amount = 10;
Создаем транзакцию:
use Minter\SDK\MinterTx;use Minter\SDK\MinterCoins\MinterSendCoinTx;$tx = new MinterTx([‘nonce’ => $nonce,‘chainId’ => MinterTx::MAINNET_CHAIN_ID,‘gasPrice’ => 1,‘gasCoin’ => ‘BIP’,‘type’ => MinterSendCoinTx::TYPE,‘data’ => [‘coin’ => ‘RATING’,‘to’ => $userAddress,‘value’ => $amount],‘payload’ => ‘’,‘serviceData’ => ‘’,‘signatureType’ => MinterTx::SIGNATURE_SINGLE_TYPE]);
Подписываем транзакцию приватным ключом от адреса, на котором хранятся монеты RATING.
$transaction = $tx->sign($mainAddressPrivateKey);
3. Отправляем подписанную транзакцию в сеть.
use GuzzleHttp\Exception\RequestException;try { $response = $api->send($transaction);} catch(RequestException $exception) {// short exception message$message = $exception->getMessage();// error response in json$content = $exception->getResponse()->getBody()->getContents();// error response as array$error = json_decode($content, true);}
4. Определять рейтинг и категорию пользователя (например, для предоставления подписки уровня Silver, Gold или Platinum) мы можем по количеству монет на балансе его адреса. Для этого мы можем получить баланс и определить рейтинг.
use Minter\MinterAPI;$nodeUrl = ‘https://minter-nodes-1.mainnet.minter.network:8841′;$api = new MinterAPI($nodeUrl);$response = $api->getBalance($address);$balance = $response->result->balance;$ratingAmount = $balance->RATING ?? 0;$userCategory = ‘Junior’;if ($ratingAmount >= 10) {$userCategory = ‘Middle’;}if ($ratingAmount >= 30) {$userCategory = ‘Senior’;}echo $userCategory;
На данный момент техническая имплементация каждого из вышеуказанных кейсов возможна лишь посредством разработки собственного решения. Плагины для различных CMS — например, WordPress — будут создаваться членами сообщества и добавляться в это руководство по мере их появления и последующего аудита. Состояние актуальности информации, представленной в данном документе, вы всегда можете проверить по дате, указанной в шапке.
Юридическая часть
Minter — система, позволяющая вести децентрализованный учет виртуальных единиц — токенов. Базовым токеном является BIP, на его основе можно создавать индивидуальные, «брендированные» токены.
Minter может использоваться в качестве системы взаиморасчетов при продаже товаров и оказании услуг, а также в качестве системы учета для программ лояльности.
Настоящий гайд призван помочь в разработке схем внедрения продуктов на базе Minter в бизнес, осуществляемый на территории РФ. Этот документ не является юридической консультацией, и его авторы не рекомендуют осуществлять внедрение системы Minter без предварительной консультации с независимым юристом и бухгалтером.
Два возможных подхода к имплементации Minter — это использование базового токена BIP в качестве единицы взаиморасчета в сделках и использование «брендированных» токенов в бизнес-модели, например, для создания программы лояльности.
1. Токены как единица взаиморасчета
1.1. Гражданско-правовые аспекты
С точки зрения российского гражданского законодательства правовой статус токена не определен; мы полагаем, что до принятия соответствующего регулирования стоит ориентироваться на судебные решения, признающие сущности, схожие с учетными единицами в сети Minter, иным имуществом.
Это позволяет сразу очертить ряд возможных сделок с использованием токенов:
| Токены <–> рубли
В данной ситуации можно говорить о сделке купли-продажи токенов за рубли. К этой сделке будут применяться общие правила о купле-продаже; специфического регулирования данной сделки на момент публикации настоящего документа нет. Вместе с тем в ситуации, когда сделка совершается с крупной суммой, разумным было бы проводить идентификацию контрагента для соответствия требованиям 115-ФЗ.
| Токены <–> вещи
Поскольку токены могут признаваться иным имуществом, постольку договор, по которому одна сторона передает токены, а другая сторона — вещи, будет признаваться договором мены. К договору мены в части, не противоречащей сути отношений, применяются правила о договоре купли-продажи; в данном случае это не играет особенной роли.
Возможны практические сложности в ситуациях, когда либо сам договор, либо право собственности на передаваемое по нему имущество подлежит государственной регистрации — в первую очередь речь идет о сделках с недвижимостью. Несмотря на то, что Росреестр формально не проводит правовую оценку условий договора, его сотрудники порой склонны к самодеятельности и могут приостанавливать регистрацию при виде нетипичной конструкции.
В случае, когда по договору передается автомобиль, регистрация в ГИБДД не несет гражданско-правового значения и совершается не для перехода права собственности на автомобиль, а для допуска транспортного средства к использованию — поэтому оценка условий договора при регистрации автомобиля производиться не должна.
| Токены <–> услуги/работы/права на результаты интеллектуальной деятельности
В этом случае речь будет идти о смешанном договоре, по которому одна сторона оказывает услуги/выполняет работы/передает права на РИД, а другая — передает имущество в виде токенов. Возможность заключения таких договоров следует из статьи 421 Гражданского кодекса.
1.2. Налоговые аспекты
| Налог на прибыль организаций
Исходя из позиции, указанной в Письме Минфина от 9 февраля 2018 г. N 03–03–06/1/8061, организация определяет налогооблагаемую базу в соответствии со статьей 247 НК РФ в качестве разницы между полученными доходами и произведенными расходами в связи со сделками с токенами.
Организации могут внести соответствующие изменения в свою внутреннюю учетную политику и прописать порядок определения налоговой базы по операциям с криптовалютами, руководствуясь упомянутой выше позицией Минфина.
| НДС
На данный момент отсутствует позиция регуляторов по необходимости обложения сделок с криптовалютой НДС.
| НДФЛ
В письме Минфина от 8 ноября 2018 г. N 03–04–07/80764 предлагается определять налоговую базу по НДФЛ от операции купли-продажи криптовалют как превышение доходов от продажи криптовалюты над суммой документально подтвержденных расходов на ее приобретение.
1.3. Бухгалтерские аспекты
С точки зрения бухгалтерии отображать токены возможно в качестве финансового вложения (58 счет в плане счетов), по которому не определяется текущая рыночная стоимость, а в бухгалтерском учете на отчетную дату отразить по первоначальной стоимости (п. п. 19, 21 ПБУ 19/02).
Рекомендуется разработать и прописать порядок бухгалтерского учета операций с токенами во внутренней учетной политике.
2. Кастомные монеты как баллы лояльности
Другим способом использовать Minter в своем бизнесе может быть имплементация кастомных монет в качестве баллов лояльности.
2.1. Гражданско-правовые аспекты
С точки зрения гражданского права, предоставление скидки является правом.
В этой ситуации кастомную монету можно использовать в качестве бонусного балла, предъявление которого позволяет предоставить клиенту скидку на соответствующий товар/услугу.
2.2. Налоговые аспекты
| Налог на прибыль организаций:
Налогоплательщик может уменьшить свои доходы на сумму произведенных расходов (п. 1 ст. 252 НК РФ). В состав внереализационных расходов входят расходы в виде скидки (подп. 19.1 п. 1 ст. 265 НК РФ).
| НДФЛ:
Существующая практика судов по вопросам возникновения НДФЛ в связи с получением скидок по бонусным баллам складывается в пользу налогоплательщиков. Так, полученные физическими лицами скидки и бонусные баллы не являются объектом налогообложения НДФЛ, соответственно, компании не должны выступать налоговыми агентами, и клиенты компаний могут без опасений участвовать в программах лояльности и накапливать бонусные баллы.
2.3. Бухгалтерские аспекты
Обязанность компании по предоставлению скидок на товары и услуги в связи с наличием у клиента бонусных баллов («брендированных» токенов) может трактоваться как «оценочное обязательство», условия и порядок признания которого определены п.4 и 5 Положения по бухгалтерскому учету «Оценочные обязательства, условные обязательства и условные активы» (ПБУ 8/2010), утвержденного Приказом Минфина России от 13.12.2010 № 167н (далее — ПБУ 8/2010).
Отражение фактов хозяйственной деятельности на счетах бухгалтерского учета производится в соответствии с Планом счетов бухгалтерского учета финансово-хозяйственной деятельности организаций и Инструкцией по его применению, утвержденными Приказом Минфина России от 31.10.2000 № 94н.