На заре Биткоин 1.0, во время разработки платежных шлюзов для некоторых централизованных систем столкнулся с следующей проблемой - отсутствие примечания к платежу, в любой из биткоин подобных монет. И это была проблема, которая как известно решается методом выдачи каждому пользователю уникального адреса.
В данном руководстве рассматривается метод приема платежей с примечанием к платежу (сообщением) в экосистеме SmartHoldem. Сервис использует 1 адрес, но для каждого пользователя генерируется уникальная строка.
Для простоты понимания в качестве бэкенда используется язык PHP.
В процессе участвуют: сервис (обменник) и пользователь (клиент).
Клиент
Со стороны клиента некий сервис - обменник, генерирует для клиента исходные данные.
0_1522740861038_service1.jpg
сумма к получению в меняемой монете (задаваемая клиентом)
расчетный результат к получению по текущему курсу STH > COIN
адрес для отправки STH (для всех один)
уникальная строка сообщения (идентифицирует отправителя)
Здесь на стороне сервиса в backend генерируется уникальная строка для каждого пользователя и сохраняется в базу данных, к примеру таблица вида:
userid(int), msg(string)
<?php
$msg = substr(md5(uniqid(microtime(), 1)) . getmypid(), 1, 8);
// результат уникальная строка: 561559b2
Клиент, зная исходные данные, отправляет соответствующую сумму с примечанием на указанный адрес с помощью своего кошелька.
0_1522742749392_wallet_v1.jpg
Сервис
Теперь в работу вступает backend сервиса, обработчик транзакций. Для простоты понимания будем использовать выполнения скрипта по crontab.
Создаем на стороне сервера php-файл, далее пропишем его на выполнение cron каждую минуту.
<?php
$addr = 'Sg13BhANeairfS3o3w8N9sKaFrsht2bt4V'; //адрес проверки транзакций
$limit = 25; //лимит выдачи транзакций
$offset = 0; // смещение
//сортируем выдачу транзакций по timestamp с помощью orderBy
$url = 'http://your_node_ip:6100/api/transactions?recipientId='.$addr.'&orderBy=timestamp&offset=0';
//получаем данные и преобразуем в массив
$tx = json_decode(file_get_contents($url),true);
/*
если транзакций более лимита,
смещаем offset указатель выдачи транзакций и получаем последние $limit транзакций,
т.к. транзакций может быть сотни тысяч
*/
if ($tx['count'] > $limit) {
$offset = $tx['count'] - $limit; // расчет смещения
$url = 'http://your_node_ip:6100/api/transactions?recipientId=Sg13BhANeairfS3o3w8N9sKaFrsht2bt4V&orderBy=timestamp&offset='.$offset;
$tx = json_decode(file_get_contents($url),true);
}
// обрабатываем данные
for ($i = 0; $i < count($tx['transactions']); $i++) {
print "<br>amount:".$tx['transactions'][$i]['amount'].
" timestamp:".$tx['transactions'][$i]['timestamp'].
" msg:".$tx['transactions'][$i]['vendorField'].
" senderId:".$tx['transactions'][$i]['senderId'].
" Txid:".$tx['transactions'][$i]['id'];
/*
здесь выполняем необходимые проверки и операции записи в базу данных,
к примеру добавляем баланс
сохраняем в таблицу транзакций уникальные транзакции,
которые и проверям при получении,
к примеру txid, userid, timestamp, sum_sth, sum_coin
*/
/*
помним, баланс выдается в сатоши,
не забываем его преобразовать точными функциями
*/
$sumCOIN = bcdiv($tx['transactions'][$i]['amount'],100000000,8);
$set['btc_sth'] = 1; //курс по отношению к STH
$sumBTC = bcdiv($sumCOIN, $set['btc_sth'], 8); //расчитываем курс монеты
}
Вот и все, транзакция обработана, операция выполнена.
Новые операции
+BTC за STH
1.28 BTC / 0.32000000 STH
03.04.18 09:59
пример не претендует на качество кода, он предназначен для базового понимания приема платежей.
Возможно в свою ноду интегрировать событийный скрипт с колбаками, к примеру считывать получение нового блока, затем находить транзакции предназначенные для вашего адреса, но это более сложный подход к простому приему транзакций, хотя и более элегантный.
P.S. Событийный подход мы рассмотрим в следующих публикациях.
P.P.S. Функция отправки сообщений будет доступна в версии кошелька 1.0 в ближайшие дни/неделю, с сотнями других дополнений и исправлений.