NXTER.ORG

10 Cities Names

Добро пожаловать в космос. Мы это сделали.

На этой неделе мы посмотрим из космоса на 10 разных городов.

Узнай названия городов, запиши их строчными буквами, разделяя пробелами
- и дождись анонса 11-го и 12-го города.
Эти 12 названий городов сформируют парольную фразу, которая дает доступ к аккаунту, на котором лежат 500 IGNIS.

Следите за местами, где обычно собираются Некстеры.

Пока не известно, где именно будут объявлены названия 11-го и 12-го городов.

ГОРОД 11

День
Час
Минута
Секунда

ГОРОД 12

День
Час
Минута
Секунда

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

NxterPuzzle | Путешествие по Молдове

Итак… кто-то нашел секретный пароль к аккаунту Алисы. Спустя 23 после выпуска недавнего ребуса Nxter, IGNIS ушел. Некоторым читателям показались сложными правила. Другие же не пожалели потратить часть своего драгоценного времени на решение головоломки с наградой 4$. Узнав об этом, madfox, создатель ребусов, ответил в личной беседе:

madfox [9:41 PM]

これは新しいパズルです…..

На этой неделе мы решили сосредоточить наше внимание на Республике Молдова, Восточная Европа.

Задание представляет собой прямоугольную сетку, разделенную на регионы произвольной формы. Необходимо провести замкнутую линию через все клетки так, чтобы линия заходила и выходила из каждого региона только один раз. Линия состоит из вертикальных и горизонтальных отрезков, соединяющих центры соседних клеток. Линия не должна пересекать саму себя. Направление движения отмечено красной стрелкой. Парольная фраза представляет собой слово, состоящее из цифр, пересекаемых линией путешествия. Пароль дает доступ к призовому аккаунту ARDOR-L4GP-7DUP-X459-72F5E.

Кликните по картинке, чтобы ее увеличить

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

Примечание.

Madfox пишет:

Вижу два варианта ребуса для второго сентябрьского выпуска:

1 — Простая головоломка с последним недостающим словом, которое будет объявлено
2 — Очень сложная :slightly_smiling_face:

На этой неделе ребус Nxter вновь любезно спонсирован Ardor and Nxt Group.

Summer Quest

Летний Квест - часть серии головоломок Nxter, создаваемых madfox и спонсируемых ANG.

Добро пожаловать.

Летний Квест приглашает вас совершить путешествие, в котором вы будете прогуливаться по частям света в поисках особых чисел и слов. Слова на каждом этапе квеста дадут вам доступ к аккаунту Ignis, который содержит зашифрованное входящее сообщение. Отыщите все слова и заберите финальный приз: 1000 IGNIS.

madfox пишет:

Приготовьтесь к путешествиям!

Используйте Google Maps для исследования некоторых городов, имеющих значение для участников проекта Ardor/Nxt; в этой охоте за 1000 IGNIS гуляйте по виртуальным улицам и найдите скрытые слова. Для победы вам необходимо пройти все этапы квеста.

В выпуске новостей Nxter  (Июль V) представлены Этап I + Этап II. Все 12 слов этих двух этапов составляют парольную фразу, дающую доступ к аккаунту в блокчейне Nxt/Ardor. Парольная фраза открывает зашифрованное сообщение, которое находится в этом аккаунте, чтобы дать вам возможность узнать, что ваше решение верное. Прочтите сообщение, сохраните эту парольную фразу и ждите следующий этап.

После Этапа 5 для получения итоговой парольной фразы, открывающей призовой аккаунт с 1000 IGNIS от щедрой ANG,  вам останется узнать только одно слово. Это финальное слово будет объявлено в ходе фестиваля Hackathon / Gamejam 24-26 августа в Австрии, оставайтесь с нами.

Итак, вот формула финальной парольной фразы:
(Этап I + Этап II) + Этап III + Этап IV + Этап V + ФИНАЛЬНОЕ СЛОВО. Все буквы строчные, разделены пробелами - в точности, как в парольной фразе к любому вашему аккаунту Ardor.

В течение всего мероприятия на аккаунты Летнего Квеста без объявления могут рассылаться случайные бонусы в виде монет или токенов на основе NXT или Ardor. Некстеры, в руках которых будут парольные фразы от аккаунтов Летнего Квеста, смогут забрать эти бонусы в свои аккаунты по принципу - кто успел, тот и съел. Удачных странствий!


ЭТАП 1

Первый район поисков - Хадера, Израиль, где живет Lior Yaffe (сооснователь, управляющий директор @Jelurida).

Хадера

Отыщите в этом районе (используя Google maps) скрытые слова в соответствии с нижеприведенными изображениями.

 

Нажмите на картинку, чтобы ее увеличить


ЭТАП 2

Второй район поисков -  Ланкастер, Пенсильвания, город Elizabeth Mong, Директора Ardor and Nxt Group (ANG).

Ланкастер, Пенсильвания

Википедия:

В 2009 году увеличение сети камер с 70 до 165 в Ланкастере привлекло внимание нации, включая заголовок на первой полосе Los Angeles Times: “Ланкастер, Пенсильвания внимательно следит за собой”. Статья цитировала главу городской полиции Кейта Сэдлера: "Еще несколько лет назад мы не способны были это осуществить...Это напоминает Большого Брата, Джорджа Оруэлла и 1984. Забавно, насколько спокойно американцы это приняли".

Это особенно забавно, если вы знаете историю Nxt > Ardor. Короткая версия.

Прогуляйтесь по району поисков и отыщите (используя Google maps) скрытые слова в соответствии с нижеприведенными изображениями.

Нажмите на картинку, чтобы ее увеличить

В путь!

ПОДСКАЗКА: Когда вы "найдете" аккаунт, его балансы NXT и ARDR/монет дочерних цепей можно проверить с помощью нашего онлайн nxter.org/explorer. С Nxter Alerts вы будете уведомлены по электронной почте о любых входящих или исходящих транзакциях с любого Nxt или Ardor/дочерняя цепь аккаунта, на который вы подписаны.

Чем хорош Ignis?

Недавно в подреддитах Nxt и Ardor было несколько постов, в которых звучали вопросы об Ignis: Зачем Jelurida его создала? Какие проблемы он решает? Почему люди должны захотеть его использовать?

Я предполагаю, что для давних членов сообщества Nxt ответы на эти вопросы очевидны. Для новичков же разобраться в применении технологии Nxt/Ardr выглядит забавным (и полезным) упражнением. С этим чувством я ответил на один из этих постов, поделившись своими некоторыми мыслями о возможном использовании Ignis. Мне кажется, нашим читателям будет интересно услышать их, поэтому я публикую свои идеи тут, чтобы вы могли над ними поразмыслить.

Итак, что же такого особенного в Ignis? В двух словах, Ignis единственная дочерняя цепь на платформе Ardor, которая гарантированно поддерживает все доступые функции.  В своей основе у нее есть все функции, которые есть у Nxt в настоящий момент, плюс несколько новых (см. отличное описание, сделанное apenzl для обзора нового функционала). Если вы новичок в Nxt и Ardor и пока еще не провели достаточно времени, разбираясь с  полной версией клиента, я настоятельно рекомендую вам это сделать. Удивительно, как много вы можете сделать, используя встроенные функции.

IGNIS

Без дальнейших церемоний, вот несколько примеров использования Ignis, большинство из которых также применимы к Nxt.

Совместное владение имуществом

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

Децентрализованный краудфандинг

Предположим, вы желаете провести краудфандинговую кампанию, в которой ваши сторонники не обязаны платить, пока не будут достигнуты цели по сбору средств. Монетарная Система Ignis применяется именно для этого, помимо других своих функций. Вы можете выпустить свою собственную «валюту» (токен), которую будут покупать ваши инвесторы, установить крайний срок для сбора средств, установить условия для переноса средств при получении какой-нибудь минимальной суммы денег. Все это встроенный функционал. По мере развития вашего проекта, вы можете отсылать сторонникам сообщения с информацией о достижении важных этапов, используя Систему Сообщений. Наконец, когда ваш проект станет успешным, вы можете выплатить бонусы ранним инвесторам пропорционально количеству их токенов.

Розничная торговля

Предположим, у вас есть магазин видеоигр, и Nintendo объявляет о начале продаж Nintendo64 Classic. Вы узнаёте, что получите только ограниченное количество. Чтобы сохранить своих клиентов в этой обстановке и не допустить, чтобы они собирались перед магазином в 5 утра, чтобы первыми приобрести консоль, вы решили предложить им возможность заранее купить ваучеры, которые они могут обменять по своему усмотрению на игровую приставку. Однако, вы обеспокоены тем, что спекулянты скупят все ваши ваучеры в MSRP и перепродадут их с огромной наценкой.

Вы решаете выпустить свой ваучер через Монетарную Систему Ignis как контролируемую валюту. Это означает, что вы можете продать его по фиксированной цене, и покупатели не могут перепродать ее позже никому, кроме вас. Когда владелец учетной записи позже придет в ваш магазин, вы выкупите ваучер за «нулевую сумму» и отдадите ему или ей Nintendo64 Classic взамен.

Финтех

Предположим, вы хотите создать хедж-фонд, вроде Numerai. Вы хотите выпустить токен, который может храниться или продаваться только учеными, чьи модели вы хотите собирать и оценивать.

Сначала вы запрашиваете приложения у ученых через свой сайт и решаете, достойны ли они участвовать. Кандидаты, которых вы хотите зарегистрировать, отправляют вам свои адреса Ardor, и вы используете свою учетную запись, чтобы пометить их учетные записи специальным свойством, указывающим, что они имеют право участвовать. Затем вы выпускаете актив на Ignis, используя новые функции Asset Control и Vote by Account Property, и указываете, что ваш актив может продаваться только с помощью учетных записей с использованием свойства, которое вы использовали для обозначения права на участие. Затем вы делаете платежи со своего актива на каждый счет пропорционально тому, насколько хороши модели владельца счета, и выплачиваете дивиденды всем владельцам активов пропорционально их размерам. В результате люди, которые представляют лучшие модели, получают самую большую долю ваших дивидендов.

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

Венчурный капитал

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

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

Заключение

Эти примеры лишь верхушка айсберга, но я надеюсь, что они дали вам представление о том, на что способны Nxt и Ignis.

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

Среди прочего я бы хотел отметить, что большинство вещей, которые вы хотели бы сделать на Ethereum, также можно сделать на Ignis. Как я уже говорил, написание безопасных смарт-контрактов на Ethereum, как правило, требует, чтобы они были либо очень простыми, либо должно быть некоторое доверие между пользователями и разработчиками. В первом случае смарт-транзакции Ignis часто заменяются непосредственно на интеллектуальные контракты, а во втором случае вы можете перемещать большую часть своего кода вне сети и использовать блокчейн для частей, которые действительно должны быть ненадежными. В любом случае, я не думаю, что дополнительная гибкость, которую предлагают смарт-контракты, является таким большим преимуществом, как кажется на первый взгляд.
Поэтому, если вам интересно узнать, какая ценность в Ignis, сначала спросите себя, какая ценность есть в Ethereum. Для каждого примера применения, которое вы придумали, попытайтесь убедить себя, что вы абсолютно не можете использовать Ignis для достижения той же цели с аналогичной степенью децентрализации. Если вы разделяете мою озабоченность по поводу безопасности сложных интеллектуальных контрактов, которые поистине неизменяемы, вы сильно удивитесь, узнав, насколько похожи потенциальные применения обеих платформ….

Наконец, стоит упомянуть, что для нескольких примеров, которые я дал, могут быть значительные проблемы нетехнического характера. В частности, Комиссия по ценным бумагам США постановила несколько месяцев назад, что некоторые токены, торгуемые на блокчейнах, могут считаться ценными бумагами, особенно в тех случаях, когда инвесторы имеют «разумное ожидание прибыли, получаемой от усилий других лиц». В таких случаях эмитенты этих токенов должны зарегистрироваться в SEC для ведения бизнеса в США.

В любом случае, я надеюсь, что эти примеры конкретно указывают, насколько много функций предлагает Ignis. Если вы можете предложить другие примеры использования Ignis, добавьте их в раздел комментариев! И, как всегда, я был бы признателен за конструктивную критику.

 

Лотерея на блокчейне Nxt в Golang

В первой статье я рассказал о теории блокчейна, о том, что она может сделать для вашего программного проекта и основах взаимодействия с блокчейном Nxt в PHP.

Сегодня я собираюсь представить небольшую лотерею, написанную на Go.
Требования: Golang (тестировался с Go 1.6.2) NRS 1.10.1 (https://bitbucket.org/JeanLucPicard/nxt/downloads/)

Программа полностью функциональна и запускает лотерею каждое воскресенье [1]. Она была изначально написана на PHP, оба источника доступны для загрузки из облака данных Nxt [2].

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

Данными для этого приложения служат «билеты», отправленные пользователями во вложениях.

Участник лотереи посылает 10 NXT на счет лотереи и прикрепляет публичное незашифрованное сообщение со строкой из 5 чисел, в диапазоне от 0 до 30, разделенных запятыми. Для получения награды, сообщение должно быть незашифрованным, чтобы его можно было публично проверить с помощью блокчейна.

Приложение делает запрос к серверу Nxt, чтобы извлечь все транзакции из лотерейного счета, сортирует их, выбирает только действительные транзакции и создает срез карт (многомерный массив в PHP) учетных записей игроков и строки их чисел. Оно также рассчитывает общую сумму NXT, выплачиваемую игрокам из суммы всех действительных билетов.

Получив все действительные данные, приложение проводит три раунда лотереи. Каждый раунд получает часть от общей суммы выплат, разделенных между победителями. В раунде 5, приложение находит пользователя(ей), которые правильно угадали 5 чисел, и посылает награды. В раунде 4, приложение делает то же самое для пользователей, которые угадали 4 числа, срез участвующих билетов теперь меньше на количество победителей раунда 5. Аналогично для раунда 3.

В этом суть.

Немного подробностей

Для каждого из трех раундов лотерея генерирует последовательности 5 чисел и сравнивает их со строками чисел в билетах, пока один или несколько победителей не будут найдены. Можно сказать, что «силы» лотереи это выигрышная последовательность на билетах.

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

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

func genFive(seed string) [5]int {
   var r [5]int
   seedInt, _ := strconv.Atoi(seed)
   d := false
   for a := offset; a < offset+5; a++ { 
      rand.Seed(int64(seedInt + offset)) 
      var dup [31]int 
      d = false 
      r[0] = rand.Intn(31) 
      r[1] = rand.Intn(31) 
      r[2] = rand.Intn(31) 
      r[3] = rand.Intn(31) 
      r[4] = rand.Intn(31) 
      for _, v := range r { 
         dup[v]++ 
      } 
      for k, _ := range dup { 
         if dup[k] > 1 {
            d = true
         }
      }
      offset = offset + 5
      if d == false {
         return r
      }
   }
   return r
}

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

Проблема с детерминированными значениями: если они известны заранее, последовательности чисел можно предсказать и результаты лотереи могут быть подтасованы. Для решения этой проблемы мы вновь обратиться к блокчейну Nxt, чтобы найти источник значений с функцией getSeed().

func getSeed() (string, string) {
 type BlockchainStatus struct {
    NumberOfBlocks int `json:"numberOfBlocks"`
 }
 var status BlockchainStatus
 if seedBlockOutput, b := 
sendQuery("requestType=getBlockchainStatus", 
true); 
b != false { if err := 
json.Unmarshal([]byte(seedBlockOutput), &status); 
err != nil {
     fmt.Println(err)
   }
  }
 seedBlockHeight := 
strconv.Itoa(status.NumberOfBlocks - 11)

 type BlockId struct {
  Block string `json:"block"`
 }
 var block BlockId
 if seedBlockId, b := 
sendQuery("requestType=getBlockId&height="
+seedBlockHeight, true); b != false {
if err := json.Unmarshal([]byte(seedBlockId), 
&block); err != nil {
         fmt.Println(err)
    }
  }
 seed := block.Block[len(block.Block)-5:]
 return seed, seedBlockHeight
}

Приложение работает в 18:00 UTC в воскресенье.

Первое, что делает функция getSeed() это извлекает идентификатор блока, который был сгенерирован 10 блоков до запуска приложения (как видно в локальной копии блокчейна на лотерейной ноде) и берет его 5 последних цифр в качестве сида. Из-за задержки сети и случайных перестроек 1-3 блоков блокчейна, лотерейная нода не может видеть тот же блок, что и другие ноды. Число 10 для получения блока для сида было выбрано, чтобы быть уверенным, что блок не будет реорганизован.

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

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

Исходный код Go не включает в себя процедуру проверки прошлых результатов.
В исходном коде PHP это есть, он является полностью функциональным и может использоваться для самостоятельной проверки всех прошлых результатов с детерминированным сидом из блокчейна.

Для Go я использую эту функцию для отправки запросов к Nxt серверу и возврату результата.

func sendQuery(Query string, Active bool) 
(output string, b bool) {
   output = ""
   b = false
   if Active == false {
      output = "Function disabled"
      return
   }
   body := strings.NewReader(Query)
   req, err := http.NewRequest("POST", 
"http://127.0.0.1:7876/nxt", body)
   if err != nil {
      output = fmt.Sprintf("%s", err)
      return
   }
   req.Header.Set("Content-Type", 
"application/x-www-form-urlencoded")

   resp, err := http.DefaultClient.Do(req)
   if err != nil {
      output = fmt.Sprintf("%s", err)
      return
   }
   bo, err := ioutil.ReadAll(resp.Body)
   defer resp.Body.Close()
   output = fmt.Sprintf("%s", bo)
   match, _ := 
regexp.MatchString(".*errorDescription.*", 
output)
   if match == true {
      fileHandle, _ := 
os.OpenFile("./error.log", os.O_APPEND, 0666)
      writer := bufio.NewWriter(fileHandle)
      defer fileHandle.Close()
      fmt.Fprintln(writer, output)
      writer.Flush()
      return
   }
   b = true
   return
}

Результаты возвращаются в виде строки JSON и должны быть распакованы в правильные структуры.

validPlayers := make([]map[string]string, 0)

lotteryAccount := "NXT-YXC4-RB92-F6MQ-2ZRA6"

type Attachment struct {
   Message       string `json:"message"`
   MessageIsText bool   `json:"messageIsText"`
}

type Transaction struct {
   Timestamp   int        `json:"timestamp"`
   AmountNQT   string     `json:"amountNQT"`
   ID          string     `json:"transaction"`
   SenderRS    string     `json:"senderRS"`
   RecipientRS string     `json:"recipientRS"`
   Attached    Attachment `json:"attachment"`
}

type Response struct {
   Transactions []Transaction 
`json:"transactions"`
}
Query := 
"requestType=getBlockchainTransactions&account=" +
lotteryAccount + 
"&type=0&subtype=0&executedOnly=true"

if v, a := sendQuery(Query, true); a == true {
   var transactions Response
   if err := json.Unmarshal([]byte(v), 
&transactions); err != nil {
      fmt.Println(err)
   }

 p := 0
 for k, _ := range transactions.Transactions {
    // code to check tickets for validity.
    // if transaction satisfies all criteria 
    // add it to the slice of valid tickets.
		
    validPlayers = append(validPlayers, 
make(map[string]string))
    validPlayers[p][txSender] = lotteryNumbers
    p++
			
   }
}

Теперь, когда «validPlayers» имеет все хорошие билеты мы можем начать игру.

process() получает целое число (5, 4, или 3) и другие параметры, в том числе validPlayers и запускает три раунда лотереи. Делает вызов функции getWinners(), которая вызывает один раз genFive(), чтобы генерировать последовательности чисел, пока, по крайней мере, один победитель не будет найден. getWinners() возвращает результаты функции process(), которая посылает награду, удаляет билет победителя из подходящих билетов и возвращает оставшиеся билеты функции main() для последующих раундов. Существует вспомогательная функция preparePlayers(), которая воссоздает validPlayers без пустых мест, освобожденных от удаленных билетов.

Я призываю каждого программиста попробовать кодить на блокчейне Nxt. Это очень легко с его богатым API, навешенным на всю функциональность ядра. https://nxtwiki.org/wiki/The_Nxt_API

Моим следующим приложением будет, вероятно, приложение опроса, с неизменными записями голосов, сохраненных в блокчейн. Как вы думаете, приложение, вроде этого может найти применение в современном мире? Кстати, Nxt имеет свою собственную встроенную систему голосования. Легко забыть, что есть в Nxt, потому что он имеет так много возможностей, и все эти функции доступны через API, программируемый разработчиками ядра для пользователей. Вы можете «намайнить» ваши первые монеты NXT, чтобы провести транзакции в проекте Удачная нода (Lucky node), запустив работающую публичную ноду, перейдите на nxtforum.org, и вы узнаете, как это сделать.

Пожалуйста, оставьте свои комментарии и предложения.


1. Лотерея на nxtforum.org.

2. Чтобы получить доступ к облаку данных Nxt Data, загрузите и установите NRS (Nxt Reference Software 1.10.1) и найдите ключевое слово ‘lottery’. Исходный код также можно загрузить с любого из публичных серверов Nxt с открытым API, например:

Go: http://23.94.134.161:7876/nxt?requestType=downloadTaggedData&transaction=7872865106538381099&retrieve=true

PHP: http://23.94.134.161:7876/nxt?requestType=downloadTaggedData&transaction=13031806327722095646&retrieve=true
НАЗАД К СТАТЬЕ.

Программирование блокчейна 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