NXTER.ORG

Программирование блокчейна Nxt для удовольствия и прибыли

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

Поскольку каждый узел проверяет все транзакции, записанные в блокчейн и прошлые транзакции не могут быть отменены или подделаны, как в традиционных базах данных RDBMS («Система управления реляционными базами данных» (Relational Database Management System)), эта избыточность делает блокчейн *неизменным*, и это очень важная ценность блокчейна. Неизменность данных является тем, что не могут обеспечить традиционные базы данных. Вам может и не понадобиться неизменность данных и подтверждение без доверия.

В этом уроке я предполагаю, вам это нужно.

В Nxt один из самых универсальных и гибких блокчейнов ( https://nxt.org ). Он насчитывает более ста API вызовов https://nxtwiki.org/wiki/The_Nxt_API

Сегодня вы узнаете основы программирования блокчейна Nxt. Я буду использовать только два вызова API в этом учебнике. С более ста API вызовами возможности для программистов безграничны.

Логика приложения

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

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

Nxt позволяет передавать и записывать произвольные сообщения (arbitrary messages — AM) в свой блокчейн.

Каждая транзакция в блокчейне проходит с комиссией. Если размер транзакции велик, то она может быть дорогой; к счастью, Nxt имеет подтип сообщений называемых prunable (урезанные) сообщения. Они обрезаются после 90 дней, и становятся дешевыми, сообщения доступны для извлечения из архивных узлов после 90 дней.

Максимальный размер произвольного сообщения в блокчейне Nxt составляет ок. 42 КБ, размер одного блока. Урезанное сообщение с 1 КБ стоит 1 NXT ($ 0,03). 1 KB достаточно, чтобы хранить хэш файла, и это окончательная стоимость, чтобы постоянно записывать один хэш в неизменный распределенный блокчейн Nxt.

По мере того как клиент загружает файл я создаю SHA256 хэш файла и храню хэш в базе данных на сервере организации. Для простоты я выбрал SQLite, но вы можете использовать MySQL, PostgreSQL, Oracle. Я буду использовать PDO (расширение для PHP, предоставляющее разработчику интерфейс для доступа к различным базам данных) для доступа к базе данных SQLite в PHP.

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

Блокчейн приходит на помощь

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

Требования:
PHP с curl, JSON и какое-нибудь расширение базы данных (я использую sqlite3). Веб-сервер не является обязательным, вы можете использовать php-cli. Java 8 (Oracle или OpenJDK для запуска Nxt). Программное обеспечение Nxt: https://nxtforum.org/nrs-releases/nrs-v1-10-1/.

Установите NRS (программное обеспечение Nxt (в зависимости от контекста называется клиент Nxt или сервер Nxt)) и создайте аккаунт. Пополните его несколькими монетами. Вы можете обменять биткон на NXT на https://shapeshift.io или обменяться с кем-то на https://nxtforum.org. Также можно «намайнить» немного NXT, как награду за запуск ноды; http://test.nxter.org/the-forging-bounty-lottery-campaign-will-pay-5-million-in-rewards-to-forgers-and-nxt-nodes/.

Сначала мы создаем простую таблицу базы данных для нашего приложения, ничего не выдумывая, вы можете добавить несколько типов столбцов, если необходимо хранить больше информации. Мне нравится использовать DB Browser для SQLite http://sqlitebrowser.org.

Давайте создадим пустую базу данных ‘files.db’ и сохраним ее в /home/lurker10/phptutorial/files.db

Используя DB Browser для SQLite создаем следующую таблицу

CREATE TABLE "files" (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`txid` TEXT,
`hash` TEXT,
`uploadtime` TEXT,
`filename` TEXT
)

‘txid’ это поле для хранения идентификатора транзакции, которую мы получаем от Nxt, когда транзакция принята. Он уникален. ‘hash’ это sha256 хэш файла.

Для краткости, в этом уроке я пропущу часть кода загрузки файла.

Давайте предположим, что файл уже загружен и сохранен на веб-сервере. Определим переменную местоположения файла в коде.

$uploadDir = "/home/lurker10/phptutorial/tmp/";
$fileName = "copy12345.tar";

По умолчанию Nxt сервер прослушивает запросы API на порт 7876. Если вы запустите его на той же машине, что и ваш код PHP, ваш код должен посылать запросы на http://127.0.0.1:7876/nxt

Другими важными переменными являются секретная фраза (passphrase), созданного и пополненного вами аккаунта Nxt и счет получателя.

Вы можете отправить сообщение самому себе, получателем может быть свой собственный счет.

$host = "http://127.0.0.1:7876/nxt";
$secretPhrase = "your passphrase";
$recipientID = "NXT-XXXX-XXXX-XXXX-XXXXX";

Следующая часть кода является функцией, которая отправляет запрос с использованием curl в POST-запросе.

Чтобы сделать запрос, мы должны определить переменные $payload и $payload_string и скормить их sendRequest(). Можно запустить сервер Nxt через HTTPS и использовать curl для проверки сертификата SSL, но для этого простого приложения мы отключили проверку SSL.

Еще одним интересным объектом является $errorDescription, json-декодированный ответ сервера.

Если есть проблема с запросом («Не хватает средств» на вашем аккаунте, когда ваш баланс равен нулю),
вы должны добавить процедуру обработки ошибок. Я это тоже опускаю. Для этого приложения я предполагаю, что сервер ответил правильно, и возвращает ответ в приложение для дальнейшей обработки.

function sendRequest($host, $payload, $payload_string) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $host);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 10000);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 10000);
curl_setopt($ch, CURLOPT_POST, count($payload));
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload_string);
$output = curl_exec($ch);
$curl_error = curl_error($ch);
curl_close($ch);
$errorDescription = trim(@json_decode($output)->errorDescription);
if ($errorDescription != "") { // perform error handling; return false; }
return $output;
}

По мере того как файл загружен, я создаю SHA256 хэш файла и временную метку.

$fileHash = hash_file("sha256", $uploadDir.$fileName);
$txTime = time();

Я буду использовать PDO для работы с базой данных

Откройте БД и вставьте новую запись.

Мы не знаем TXID, пока не поговорим с сервером Nxt, который даст нам его, при принятии транзакции в сети, так что теперь я буду вставлять NULL для TXID.

$pdo = new PDO('sqlite:/home/lurker10/phptutorial/files.db');
$sql = "INSERT INTO files (txid, hash, uploadtime, filename)
VALUES (null, '$fileHash', '$txTime', '$fileName')";
$result = $pdo->exec($sql);

Далее мы создаем запрос для отправки на Nxt серверу.

Конкретный запрос «sendMessage», вы можете найти больше запросов для взаимодействия с блокчейном и их обязательные и необязательные параметры на https://nxtwiki.org/wiki/The_Nxt_API.

Как я уже говорил комиссия за транзакцию составляет 1 NXT. 1 NXT = 100,000,000 NQT (nanoquants).
1 NQT это наименьшая единица в NXT же, как 1 сатоши в биткоин.
Nxt Сервер принимает комиссии в NQT, поэтому мы платим ровно 100 миллионов NQT ($0.03)

Параметр «broadcast» может быть изменен на false, в этом случае вы получите «transactionBytes в ответе, который может транслироваться в сеть позже, используя запрос ‘broadcastTransaction’. Но сегодня я поставил его на «true» для мгновенной передачи сделки.

Не забудьте кодировать URL (urlencode()) сообщения. Я вставляю имя файла, отделенное двоеточием от хэша, в сообщение.

$payload = array(
"requestType" => "sendMessage",
"recipient" => $recipientID,
"secretPhrase" => urlencode($secretPhrase),
"feeNQT" => 100000000,
"deadline" => 1440,
"broadcast" => "true",
"message" => urlencode($fileName . ":" . $fileHash),
"messageIsPrunable" => "true"
);
$payload_string = "";
foreach ($payload as $key => $value) {
$payload_string .= $key . "=" . $value . "&";
}
rtrim($payload_string, "&");

Отправьте запрос на сервер Nxt с помощью функции SendRequest():

$output = sendRequest($host, $payload, $payload_string);

и декодируйте JSON ответ сервера, чтобы получить идентификатор транзакции:

if ($output != false) {
$txId = json_decode($output)->transaction;
}

Теперь, когда есть положительный ответ от принятой транзакции и известно ее ID, давайте обновим запись в БД.

$lastId = $pdo->lastInsertId();
$sql = "UPDATE files SET txid = '$txId' where id = '$lastId'";
$result = $pdo->exec($sql);

Мы можем предоставить при необходимости эти ссылки заказчику для использования в будущем и доказать, что хэш был загружен:

echo "NXT Transaction ID: " . $txId . ",
JSON response";
echo "

Используйте эти ссылки для проверки SHA256 хэша файла, сохраненного в нашей внутренней базе данных с неизменной записью в блокчейне Nxt:

" . $fileHash;

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

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

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

Теперь запись сохранена в базе данных компании. Показать запись БД, чтобы подтвердить, что она есть.

$sth = $pdo->prepare("SELECT id, txid, hash, uploadtime, filename FROM files ORDER BY id DESC");
$sth->execute();
$result = $sth->fetch(PDO::FETCH_OBJ);
if ($result != false) {
var_dump($result);
}

Приложение проверки

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

Предположим, что он есть у клиента, сохраненный в почтовом архиве или извлеченный с помощью других средств.
Вот.

$txId = "111111111111111111";

Давайте посмотрим, что есть в нашей базе данных для хэша файла. Получим и сохраним его в $hashInDb.

$pdo = new PDO('sqlite:/home/lurker10/phptutorial/files.db');
$sth = $pdo->prepare("SELECT hash FROM files where txid = '$txId'");
$sth->execute();
$result = $sth->fetch(PDO::FETCH_OBJ);
if ($result != false) {
$hashInDb = $result->hash;
}

Отправляем запрос на сервер Nxt и получаем всю информацию, хранящуюся в блокчейне Nxt для сделки с указанным идентификатором.

$payload = array (
"requestType" => "getTransaction",
"transaction" => $txId
);
$payload_string = "";
foreach ($payload as $key => $value) {
$payload_string .= $key . "=" . $value . "&";
}
rtrim($payload_string, "&");

$output = sendRequest($host, $payload, $payload_string);

Декодируем ответ в формате JSON и извлекаем поле вложения, где хранится хэш.

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

$attachmentPlainData = json_decode($output)->attachment->message;
$hashInBlockchain = explode(":", $attachmentPlainData)[1];

И сравниваем то, что имеем в базе данных компании с тем, что было записано 1 год назад в блокчейне Nxt.

if ($hashInDb == $hashInBlockchain)
echo "Hashes are identical";
else
echo "Hashes are not identical";

NXT-crypto-developer

View this in: English Français Español

Оставьте комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.