Pages:
Author

Topic: 🔹🅰RK🔹[ANN] ARK - Криптoвaлютнaя Экocиcтeмa🔹 ICO Зaвepшeнo (Read 103832 times)

hero member
Activity: 520
Merit: 11957
Так, теперь насчет пустой функции IPC. Так как она будет обрабатываться в макете игры, а не в лобби, мы добавим новую глобальную переменную в Game Event Sheet (листе событий игры). Переключитесь на это, щелкните правой кнопкой мыши на пустом листе и выберите Add global variable (Добавить глобальную переменную). Назовите ее GameAddress, которая должна быть String (Строка). Добавить еще одну глобальную переменную под названием TurnAddress, которая также должна быть String. Вернитесь к нашему Lobby Event Sheet (листу событий лобби) и в функции IPC добавьте пару действий. Первым будет System > Set Value (Система > Установить значение) и выберите установку переменной GameAddress в значение Message (Сообщение). Нашим вторым действием будет System > Go to layout (Система" > "Перейти к макету). Выберите Game Layout (макет игры) из списка, нажмите Done (Готово) и теперь мы действительно закончили с нашим лобби!


Наша функция IPC очень проста!

Вся оставшаяся работа будет проходить в Game Layout (макет игры) и Game Event Sheet (игровой лист событий). Мы разработаем дизайн нашей доски и дисков, а также добавим текст, указывающий, чей ход и статус игры. Для этого перейдите к нашему Game Layout (игровой макет).

Щелкните правой кнопкой мыши по нашему пустому макету и выберите Insert new object (Вставить новый объект). На этот раз мы добавим Sprite (спрайт). Назовите его Board и вы увидите, что открыт Animations (редактор анимаций). Выберите инструмент Fill (Заполнить) и выберите цвет доски на вашем выбор, а затем заполните спрайт этим цветом. Закройте редактор анимаций и измените размер нашей платы до 480x480 пикселей.


Заполнение нашей доски синим цветом

Повторите процесс, добавив еще один спрайт. На этот раз назовите его Disc и нарисуйте белый круг с помощью инструмента Ellipse. Назовите имя анимации 0, а также установите Speed (Скорость) и Repeat Count (счетчик повторов) на 0. Щелкните правой кнопкой мыши на 0 в Animations (панель анимации) и выберите Duplicate (Дублировать). Вызовите дублированную анимацию 1. Дублируйте ее еще раз и вызовите 2. Выберите 1 и заполните круг красным цветом. Выберите 2 и заполните круг желтым цветом. Это наши игровые диски: игрок 1 будет красного цвета, игрок 2 - желтого.


3 анимации наших дисков: белый, красный и желтый

Закройте Animations Editor (Редактор анимаций) и нажмите на наш новый диск в макете. Выберите опцию Instance variables (примеры переменных) в окне Properties (Свойства) и выберите Add new instance variable (Добавить пример переменной). Вызовите имя Column с типом номера. Добавьте еще один пример переменной и назовите его Row, опять же с типом номера. Размер нашего диска 60x60 и поместите его в левый нижний угол доски. Скопируйте и вставьте наш объект диска, чтобы построить сетку из 7 столбцов и 6 строк. Щелкните каждый диск и правильно установите значения переменных Column и Row instance, поэтому нижний левый диск - Column 0, Row 0, следующий вверх - Column 0, Row 1, и так далее, при этом нижний правый диск - Column 6, Row 0, а верхний правый диск - Column 6, Row 5. Помните, что массивы JavaScript начинаются с 0!


Выбранный диск в Column 4, Row 2

Почти готово! Нужно добавить текстовое поле, чтобы указать, чей ход, или если игра окончена. Давайте сделаем это прямо сейчас. Щелкните правой кнопкой мыши по нашему макету и выберите Insert new object (Вставить новый объект). Добавим текстовый объект и назовем его StatusText. Переместите его где-нибудь над дисками и установите цвет на белый, чтобы его можно было прочитать на синем фоне. Увеличьте ширину текстового поля так, чтобы оно покрывало всю ширину нашей доски. Последнее, что нужно сделать, это добавить объект Mouse, чтобы мы могли взаимодействовать с мышкой: так мы можем отправить игровую транзакцию с закодированным smartbridge сообщением, когда игрок кликает по столбцу, чтобы играть.

Теперь мы закончили с нашей версткой. Пора отправляться в Game Event Sheet (игровой лист событий)! Добавьте новую пустую функцию и назовите ее ParseBoard. Затем добавьте новое событие, WebSocket > On text message, действием которого является JSON > Parse. Строка JSON для анализа - WebSocket.MessageText. Теперь добавьте под-событие внутри WebSocket -> On Text Message события. Выберите JSON и затем Has Key. Введите "games" и нажмите Готово. Нажмите кнопку  (Добавить действие) для нашего вновь созданного суб-события и перейдите к System > Set value (Система > Установить значение). Мы хотим установить наш JSON объект на значение JSON.get("Games"). Нажмите Готово. Это то же самое событие, которое мы создали в нашем лобби, но нам также нужно, чтобы он срабатывало во время игры, чтобы наш клиент обновлялся при изменении состояния игры. Добавьте дальнейшее действие к этому суб-событию: Functions > ParseBoard (Функции > ParseBoard), так как эта функция будет отвечать за обновление состояния доски.

Также нам необходимо обновить доску, как только откроется макет игры, поэтому давайте создадим еще одно событие. Перейдите в System > On start of layout (Система > начать макет). Действие должно быть Functions > ParseBoard (Функции > ParseBoard).

Время писать логику ParseBoard! Мы выберем нужную игру с помощью сохраненного ранее GameAddress и покажем, чья очередь. Если адрес игрока, чья очередь совпадает с нашим собственным подтвержденным адресом, мы напечатаем "You" вместо адреса. Итак, поехали!

Code:
const games = JSON.parse(runtime.globalVars.JSON);
const game = games[runtime.globalVars.GameAddress];
let text = "";
runtime.globalVars.TurnAddress = "";
if (game.outcome === "ongoing") {
    text = `Current turn: ${game.players[game.turn]} (${game.turn === 1 ? "Red" : "Yellow"})`;
    runtime.globalVars.TurnAddress = game.players[game.turn];
} else if(game.outcome === "tie") {
    text = "Game tied!";
} else {
    text = `Winner: ${game.players[game.outcome]}!`;
}
if (runtime.globalVars.ValidatedAddress) {
    text = text.replace(runtime.globalVars.ValidatedAddress, "You");
}
runtime.objects['StatusText'].getFirstInstance().text = text;

Надеюсь, к этому моменту вы уже смогли понять, как это работает. Мы извлекаем нашу игру из списка игр с помощью переменной GameAddress, а затем проверяем, продолжается ли игра. Если да, то показываем адрес, чей это ход, и цвет, в который они играют (помните, что игрок 1 всегда красный, а игрок 2 всегда желтый). Если результат ничейный или есть победитель, мы покажем эту информацию вместо него. Также, если адрес совпадает с нашим ValidatedAddress, то есть это мы, мы заменяем этот адрес на "You". Мы также сохраняем адрес текущего игрока в нашей переменной TurnAddress, если игра не окончена, в противном случае, значение очищается.

Теперь давайте расширим наш ParseBoard еще больше, чтобы изменить цвет дисков для отображения текущего состояния доски:

Code:
const discs = runtime.objects['Disc'].getAllInstances();
for (const column in game.board) {
    let row = 0;
    for (const position of game.board[column]) {
        const disc = (discs.filter(disc => disc.instVars.Column === parseInt(column) &&             disc.instVars.Row === parseInt(row)))[0];
        disc.setAnimation(game.board[column][row].toString());
        row++;
    }
}

При этом происходит итерация по всем столбцам в данных доски, полученных из WebSocket, и задается цвет подходящего диска в каждом столбце и строке.

Теперь осталось позволить текущему игроку отправить транзакцию по игровому адресу, используя значение smartbridge для столбца, в который мы хотим поместить наш диск. Для этого мы добавим еще одно событие. Выберите Mouse > On object clicked (мышь > кликнутый объект). Мы хотим действовать, когда левой кнопкой мыши нажимаем на объект Диска. Но этого само по себе недостаточно, мы хотим выполнить это действие только тогда, когда наступит наша очередь, и если выбранный столбец не будет заполнен. Поэтому щелкните правой кнопкой мыши наше новое событие и добавьте еще одно условие. Выберите Choose Disc > Is Playing Диск > (выбрать диск >  воспроизвести) и введите "0". Это означает, что наше действие сработает только в том случае, если диск будет белым, то есть он еще не проигран (иначе это было бы 1 для красного или 2 для желтого). Наконец, мы хотим запустить это действие только тогда, когда наступит наша очередь, так что добавьте еще одно условие еще раз, и на этот раз выберите System > Compare variable (Система > Сравнить переменную). Выберите ValidatedAddress как переменную, а TurnAddress как значение.

Наше действие для этого нового события Browser > Go to URL (Браузер > Перейти на URL). Мы хотим использовать схему URI ark для отправки транзакции с кошелька нашего игрока на игровой адрес, с номинальным значением 1 arktoshi, с smartbridge сообщением столбца, в которую мы помещаем наш диск. Это может быть достигнуто с помощью следующего URL в нашем действии Construct 3: "ark:" & GameAddress & "?amount=0.00000001 &vendorField=" & (Disc.Column + 1) & "&wallet=" & ValidatedAddress


Наш завершенный Game Event Sheet (игровой лист событий)


Следующие Шаги

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

Если вы застряли в какой-то момент, обязательно проконсультируйтесь с нашими документами в учебном центре Learn ARK. Кроме того, наша команда и разработчики активны в Slack, так что не стесняйтесь обращаться к нам!
hero member
Activity: 520
Merit: 11957
Запуск HTML5 Игр В Десктопном Кошельке ARK — Часть 4

Автор: Ray.Alva
Оригинал: Launching HTML5 Games In The ARK Desktop Wallet — Part Four




Снова добро пожаловать на 4-ый урок из нашей серии, объясняющий, как запустить HTML5-игру в десктопном кошельке, написав плагин ARK Core и используя Construct 3 для клиента. В этой части мы реализуем пошаговую логику игры в нашей игре Connect 4, читая сообщения о транзакциях, отправляемые на наши сгенерированные игровые адреса, чтобы заполнить игровую доску и отслеживать, чья это очередь.


Внедрение Игровой Логики

Давайте пройдемся по правилам игры, чтобы правильно реализовать нашу логику (для примера мы используем игру connect four):


Начальное подключение доски connect four

1. Существует 7 столбцов, каждая из которых может вмещать 6 дисков.

2. Каждый игрок делает ход, чтобы вставить 1 диск в любой из не заполненных столбцов.

3. Выигрывает тот, кто первым поставит 4 своих диска в непрерывную линию по вертикали, горизонтали или диагонали. На этом игра заканчивается.

4. Если доска заполнена и никто не поставил 4 диска в правильную строку, то игра завершается вничью.

Поскольку имеется 7 столбцов, наше smartbridge сообщение  должно быть 1, 2, 3, 4, 5, 6 или 7, чтобы представлять каждый из доступных столбцов. Если игрок отправляет транзакцию с smartbridge сообщением со значением 3, то наша доска будет выглядеть так:


Smartbridge сообщение со значением 3, вставляем диск в строку под номером 3.

Если 2-ой игрок также отправит транзакцию с тройкой в качестве smartbridge сообщения, то его диск будет размещен поверх предыдущего всё в том же столбце:


Наша доска после второго хода

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

Теперь, когда мы определили логику игры, пришло время ее закодировать. Как обычно, весь наш код Core плагина живет в manager.ts, так что давайте не будем тратить время впустую и для начала его откроем! Большая часть нашей работы над Core плагином сегодня будет посвящена функции generateState, которую мы запустили в предыдущей части обучающей серии. Мы собираемся расширить ее для обработки сообщений в поле smartbridge транзакций, чтобы обновить состояние нашей игровой доски в соответствии с правилами, которые мы только что описали.

Начнем с поиска следующего блока, который мы написали в прошлый раз:

Code:
for (const transaction of transactions) {
    if (transaction.senderId !== address && transaction.senderId !== players[1] && transaction.amount === wager) {
        players[2] = transaction.senderId;
        break;
    }
}

Заменяем его на это:

Code:
let transactionCounter = 0;
for (const transaction of transactions) {
    if (transaction.senderId !== address && transaction.senderId !== players[1] && transaction.amount === wager) {
        players[2] = transaction.senderId;
        break;
    }
    transactionCounter++;
}

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

Далее вы найдете следующую строку, которую мы писали в последнем уроке:

Code:
this.gameStates[address] = { players, wager };

Замените эту строчку следующим блоком кода:

Code:
const board: Array> = [];
let turn: number = 0;
let outcome: string | number = “ongoing”;

Итак, мы объявляем несколько новых переменных: board, outcome и turn. Переменная board будет содержать массив, содержащий состояние каждого столбца на доске. Переменная outcome будет использоваться для хранения данных о том, кто выиграл игру, если она все еще продолжается, или если она ничейная, а turn определяет, чей это ход; мы обнуляем ее, пока не узнаем, что у нас есть 2 действительных участника (а затем второй игрок всегда начинает игру, так как он был последним, кто присоединился к игре).

Теперь добавьте следующий блок кода:

Code:
if (players[2]) {
    turn = 2;    for (let i = 0; i < 7; i++) {
        board.push([]);
    }    // We'll add more here
}
this.gameStates[address] = { board, outcome, players, turn, wager };

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

Далее, мы добавим следующий блок кода:

Code:
const moves = transactions.slice(transactionCounter + 1).filter(transaction => !!transaction.vendorField);for (const move of moves) {
    if (move.senderId === players[turn]) {
        const column = parseInt(move.vendorField) — 1;        
        if (!isNaN(column) && column >= 0 && column <= 6) {
              if (board[column].length < 6) {
                outcome = this.makeMove(turn, board, column);
                turn = turn === 2 ? 1 : 2;
            }
        }
    }    
    
    if (outcome !== "ongoing") {
        break;
    }
}

Итак, что делает этот блок? Вспомните нашу первую модификацию кода, в которую мы добавили счетчик транзакций. Это начинается с удаления тех ранних транзакций из нашего массива ходов, так что мы начинаем только проверять ходы, которые произошли после того, как действительный противник совпал с игровой ставкой. Мы отфильтровываем все транзакции, которые не содержат smartbridge сообщения, так как именно этот механизм мы используем для того, чтобы сделать ход на доске, так что любые транзакции без сообщения являются недействительными. Затем мы перебираем все оставшиеся транзакции, убеждаясь, что отправитель транзакции совпадает с игроком, чья очередь.

Поскольку JavaScript массивы  начинаются с 0, а не с 1, то мы должны вычесть 1 из значения smartbridge сообщения. Например, хотя первый столбец на нашей доске - 1, а последний - 7, они представлены внутри массива в виде столбцов 0 и 6 соответственно. Поэтому мы должны проверить, что значение столбца - это действительное число в диапазоне 0-6, и что столбец еще не переполнен, то есть в нем менее 6 дисков. Если у нас все в порядке, то наша рутина вызывает функцию makeMove, которую мы собираемся написать, для обновления переменной outcome. Затем мы меняем ход игрока, так что если игрок 2 сделал ход, то теперь это ход игрока 1, или наоборот.

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

И с этим наша функция generateState завершена! Последнее, что нужно сделать, прежде чем перейти к Construct 3, это написать нашу функцию makeMove. Это зависит от игры и включает в себя логику, чтобы проверить, если четыре диска в строке:

Code:
private makeMove(turn: number, board: Array>, column: number) {
    board[column].push(turn);
    let full = true;
    for (let i = 0; i < board.length; i++) {
        for (let j = 0; j < 6; j++) {
            const disc = board[i][j];
            if (disc) {
                let won = false;
                if (board[i][j + 1] === disc && board[i][j + 2] === disc && board[i][j + 3] === disc) {
                    board[i][j] = board[i][j + 1] = board[i][j + 2] = board[i][j + 3] = disc;
                    won = true;
                }                
                if (board[i + 1] && board[i + 2] && board[i + 3] && board[i + 1][j] === disc && board[i + 2][j] === disc && board[i + 3][j] === disc) {
                    board[i][j] = board[i + 1][j] = board[i + 2][j] = board[i + 3][j] = disc;
                    won = true;
                }                
                if (board[i + 1] && board[i + 2] && board[i + 3] && board[i + 1][j + 1] === disc && board[i + 2][j + 2] === disc && board[i + 3][j + 3] === disc) {
                    board[i][j] = board[i + 1][j + 1] = board[i + 2][j + 2] = board[i + 3][j + 3] = disc;
                    won = true;
                }                
                if (board[i + 1] && board[i + 2] && board[i + 3] && board[i + 1][j — 1] === disc && board[i + 2][j — 2] === disc && board[i + 3][j — 3] === disc) {
                    board[i][j] = board[i + 1][j — 1] = board[i + 2][j — 2] = board[i + 3][j — 3] = disc;
                    won = true;
                }                
                 if (won) {
                    return disc;
                }
            } else {
                full = false;
            }
        }
    }    
if (full) {
        return "tie";
    }    
    return "ongoing";
}

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

После того, как эти шаги завершены, мы официально завершаем логику нашей игры!

Теперь сохраните свою работу и запустите yarn build. Пришло время перейти к Construct 3, чтобы собрать все вместе.


Работа с Construct 3

Перейдите в наш Event Sheet 1(лист событий 1) и найдите наш ранее созданное событие On start of layout (старт макета). Щелкните правой кнопкой мыши по нашему существующему событию и добавьте скрипт, так как мы будем писать код здесь, чтобы позволить нашему iframes лобби(из предыдущей главы) взаимодействовать с нашей игрой. В частности, мы включим ссылку для просмотра текущей игры.

Code:
if (!window.addedEventListener) {
    window.addEventListener("message", event => {
        if (event.data) {
            runtime.callFunction("IPC", event.data);
        }
    });
    window.addedEventListener = true;
}

Вы заметите, что наш код вызывает функцию IPC, или меж-процессное взаимодействие. Мы должны создать эту функцию сами, но это будет очень просто. Она просто прослушает сообщение, содержащее игровой адрес, сохранит его в переменной и переместит нас в новую верстку игры. Но подождите! Прежде чем мы создадим нашу функцию, мы должны добавить новую верстку игры. Щелкните правой кнопкой мыши Layouts (Макеты) в меню Project (Проект) и выберите Add layout (Добавить макет). По желанию можно также создать лист событий. Затем, как и прежде, вернитесь к нашему Event sheet 1 (списку событий 1).


Добавление нового макета

На данный момент разумно переименовать наши макеты и таблицы событий, чтобы избежать путаницы. Щелкните правой кнопкой мыши Layout 1 (макет 1) и переименуйте его в Lobby Layout (макет лобби). Сделайте то же самое для Event Sheet 1 (список событий 1), назвав его Lobby Event Sheet (Листом событий лобби). Затем переименуйте Layout 2 (макет 2) в Game Layout (макет игры), а Event Sheet 2 (лист событий 2) - в  Game Event Sheet 2 (игровой лист событий 2).

Давайте создадим эту функцию. Щелкните правой кнопкой мыши на пустую область листа событий и выберите Add function (Добавить функцию). Назовите ее IPC и оставьте все остальное как есть. Щелкните правой кнопкой мыши по нашей новой функции и выберите Add parameter (Добавить параметр). Вызовите ее Message (Сообщение) и установите ее тип на String (Строка). Нажмите OK. Пока что мы оставим нашу функцию пустой и вернемся к ней через несколько минут.

Чтобы добавить нашу ссылку для просмотра текущей игры, мы отредактируем существующий код в нашей функции ParseLobby. Прокрутите наше событие, чтобы найти эту функцию, затем найдите следующие блоки кода:

Code:
for (const game of existingGames) {
    const wager = game.game.wager / 100000000;
    html += "
Game between " + game.game.players[1] + " and " + game.game.players[2] + " for " + wager + runtime.globalVars.Symbol + "
";
}
for (const game of ourGames) {
    const wager = game.game.wager / 100000000;
    html += "
Game between " + (game.game.players[1] === runtime.globalVars.ValidatedAddress ? "you" : game.game.players[1]) + " and " + (game.game.players[2] === runtime.globalVars.ValidatedAddress ? "you" : game.game.players[2]) + " for " + wager + runtime.globalVars.Symbol + "
";
}

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





Наша пересмотренная функция
staff
Activity: 3430
Merit: 3971
Crypto Swap Exchange
Вышел ARK Desktop Wallet версии 2.9.3
Список изменений на английском доступен по ссылке: https://blog.ark.io/ark-desktop-wallet-v2-9-3-released-6d3c4469dfd
Ребята даже на видосик запилили (тоже на английском): https://www.youtube.com/watch?v=AslAEyPZnXQ&feature=youtu.be
Сам кошелёк загрузить можно тут: https://ark.io/wallet

Хэш-суммы файлов:
Linux (ark-desktop-wallet-linux-x64–2.9.3.tar.gz)
1f1e53a0a3700edbf77dd79408e95b86bbb213e01fb66f716b2d346ad8ee1523

MacOS (ark-desktop-wallet-mac-2.9.3.dmg)
71bbe46c7dd58d6cccc1797d27a39376dffcb73825192b14b94b6107f4e0d7b8

Ubuntu (ark-desktop-wallet-linux-amd64–2.9.3.deb)
d5f553ddfe5172fc05a8fca84f7ae98de9b2be584917b7597e62d74c8a66e352

Windows X86 & X64 (ark-desktop-wallet-win-2.9.3.exe)
2d941c505fbe4d5171b17f06cf0852b333c19b9b86eb10762ab1b1d9bcff7c04

Linux-AppImage (ark-desktop-wallet-linux-x86_64–2.9.3.AppImage)
8d9a6a51e9d62d2ac63aa3f5b1660646a5a24f4c208babe00b1164e9a411c6a2[/center]

Анонс: https://bitcointalksearch.org/topic/m.54763047
legendary
Activity: 1610
Merit: 1026
Перевод. Оригинальная статья: Launching HTML5 Games In The ARK Desktop Wallet — Part Six
https://blog.ark.io/launching-html5-games-in-the-ark-desktop-wallet-part-six-ad887fd2e888

Запуск HTML5 игр в ARK Desktop Wallet - часть шестая


Добро пожаловать в заключительную часть нашего учебного цикла, посвященного запуску игры HTML5 в ARK Desktop Wallet c ARK Core и Construct 3! Мы прошли долгий путь от нашего первого урока. На данный момент мы создали целую блокчейн-игру, включающую лобби, ставки, всю игровую логику, выплату призов или возврат ставок.

Осталось настроить нашу игру для запуска в качестве плагина внутри ARK Desktop Wallet. Это повлечет за собой экспорт нашей игры в формате HTML5 и создание основного плагина для загрузки нашей игры в кошелек. Этот плагин не является тем плагином Core, который мы уже сделали, поскольку он уже завершен и работает на нашем сервере. Вместо этого мы создадим плагин Desktop Wallet, который появится в менеджере плагинов в ARK Desktop Wallet. Как только мы это сделаем, наша игра будет представлена ​​совершенно новой аудитории, которая сможет скачать, установить и играть в нашу игру!

Оптимизация вашей игры для запуска в качестве плагина в ARK Desktop Wallet

Во-первых, нам нужно экспортировать законченную игру в виде страницы HTML5 и загрузить все на доступный  Интернет HTTP-сервер. Для этого мы выбираем Project> Export в меню Construct 3.


Загрузка игры

Затем нам предоставляется ряд различных платформ, на которые мы можем экспортировать нашу игру, например HTML5, для Facebook, для Android, iOS или Windows Store. Кто знает, может быть, однажды появится возможность экспортировать напрямую в Менеджер плагинов ARK, но сейчас выберите Web (HTML5) и нажмите кнопку Далее.


Мы хотим экспортировать в веб (HTML5)

Это покажет нам другое диалоговое окно, чтобы выбрать наши параметры экспорта. Мы хотим обеспечить дедупликацию изображений, повторное сжатие изображений и использование режима простой минимизации. Это экономит место и уменьшает размер данных в нашей игре. Затем нажмите Next, и процесс экспорта начнется. Это может занять несколько минут, поэтому возьмите свой любимый напиток и сделайте заслуженный перерыв!


Наши выбранные варианты экспорта

Когда это будет сделано, вам будет представлена ссылка для загрузки завершенной игры в виде ZIP-архива. Распакуйте его и загрузите его содержимое на ваш доступный в Интернете сервер. Для целей данного руководства оно было загружено по адресу https://www.arkfun.io/connect-4/.
Теперь, когда наша игра онлайн, пришло время сделать плагин Desktop Wallet. Для этого выполните действия, описанные в ARK Learning Hub, чтобы настроить подключаемый модуль Desktop Wallet. Когда вы это сделаете, мы внесем необходимые изменения, чтобы запустить нашу игру.
Прежде всего, мы собираемся отредактировать наш файл package.json, чтобы изменить некоторые разрешения. Это связано с тем, что некоторые функции настольного кошелька требуют авторизации от конечного пользователя для обеспечения безопасности.
Файл шаблона package.json из начального проекта выглядит следующим образом:

Code:
"version": "0.0.1",
    "description": "Testing my first plugin on Ark Desktop Wallet",
    "main": "src/index.js",
    "desktop-wallet": {
        "title": "My First Plugin",
        "permissions": [
            "COMPONENTS",
            "ROUTES",
            "MENU_ITEMS"
        ]
    }
}

Нам нужно добавить разрешение WEB FRAME в этот список, чтобы мы могли открывать внешние веб-страницы внутри нашего плагина. Добавьте его в новую строку сразу после пунктов меню, например:

Code:
"permissions": [
    "COMPONENTS",
    "ROUTES",
    "MENU_ITEMS",
    "WEBFRAME"
]

Мы также собираемся добавить пару новых разделов в наш файл package.json, в котором наш плагин будет отображаться в категории «Игры» ARK Desktop Wallet с некоторыми ключевыми словами, которые помогут людям найти нашу игру:

Code:
"desktop-wallet": {
    "categories": [
        "gaming"
    ]
},
"keywords": [
    "@arkecosystem",
    "desktop-wallet",
    "plugin",
    "game",
    "games",
    "gaming",
    "connect 4",
    "multiplayer",
    "pvp"
]

Обратите внимание, что первые три ключевых слова выделены жирным шрифтом. Это потому, что они необходимы для того, чтобы наш плагин появлялся в менеджере плагинов после его публикации. Любые дополнительные ключевые слова будут использоваться в поисковой системе в менеджере плагинов, чтобы помочь другим найти ваш плагин. Также не забудьте изменить имя, версию, заголовок и описание, чтобы они соответствовали деталям вашего плагина, и когда вы закончите, вы можете сохранить и закрыть файл. Теперь откройте my-first-plugin.js, который является частью плагина Desktop Wallet. Замените все содержимое на (замените , где будет размещаться ваша игра):

Code:
module.exports = {
    template: '
'
}

Вы, наверное, уже хорошо представляете, что этот код делает. Он визуализирует компонент WebFrame (помните, что ранее было разрешено WEBFRAME?) Внутри элемента
, стилизованного с использованием внутренних классов ARK Desktop Wallet, чтобы сделать компонент полноразмерным с округленными краями, чтобы он вписывался в общий эстетический стиль ARK Desktop Wallet.
Мы также установили источник WebFrame в место, куда мы загрузили нашу игру HTML5, поскольку именно это мы будем отображать в нашем компоненте WebFrame.
Сохраните наш файл, и, барабанная дробь, пожалуйста, мы внесли все необходимые изменения! Если вы перезапустите ARK Desktop Wallet и включите наш плагин из Менеджера плагинов, как описано в статье ARK Learning Hub ранее, вы должны увидеть запуск нашей игры изнутри кошелька.


Наша игра работает в ARK Desktop Wallet

Осталось только опубликовать нашу игру, чтобы другие могли ее найти и поиграть! Для этого потребуется бесплатный аккаунт на https://www.npmjs.com. Если у вас уже есть, отлично, если нет, то   зарегистрируйтесь сейчас. Затем в командной строке внутри папки, в которой вы создали плагин Desktop Wallet, введите npm login и введите свои учетные данные для входа в свой аккаунт NPM. Запустите команду npm publish --access public, и вы увидите, как по экрану летят различные фрагменты текста. Когда он будет завершен, ваша работа будет завершена, и ваш готовый плагин теперь будет доступен по всему миру в Менеджере плагинов в ARK Desktop Wallet.


Наша  игра доступна в ARK Desktop Wallet

Следующие шаги
Поздравляем, ваша игра теперь доступна в ARK Desktop Wallet! Мы надеемся, что вы нашли эту серию полезной. Это отличный способ для разработчиков добавить функциональность блокчейна в свои игры, получить дополнительный доход и представить свою игру новой аудитории!

Если вы застряли в какой-то момент, обязательно ознакомьтесь с нашими документами в центре обучения ARK. Кроме того, наша команда и разработчики активны в Slack , поэтому не стесняйтесь обращаться к нам!

Проверьте предыдущие статьи из этой серии здесь:

     Часть первая: Как импортировать адрес кошелька ARK в ваше приложение
     Часть вторая: Создание бэкенда для вашего плагина
     Часть третья: Как заставить вашу игру работать с системой ставок
     Часть четвертая: Внедрение игровой логики в ваш плагин
     Часть пятая: Реализация призовой логики
legendary
Activity: 1610
Merit: 1026
Перевод. Оригинальная статья: Launching HTML5 Games In The ARK Desktop Wallet — Part Five
https://blog.ark.io/launching-html5-games-in-the-ark-desktop-wallet-part-five-a2cf1d32be20

Запуск HTML5 игр в ARK Desktop Wallet - часть пятая


Теперь мы подошли к предпоследней части нашей серии, посвященной тому, как запускать HTML5-игры в ARK Desktop Wallet с помощью плагина ARK Core и Construct 3 . Если вы следовали за всеми предыдущими частями этой серии, вы успешно построили с нуля полностью рабочую блокчейн игру с помощью сообщений Smartbridge, сделав интеграцию лобби, для совершения ставок и пари на матч.

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

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

Это руководство полностью основано на плагине ARK Core, поэтому мы не будем вносить какие-либо изменения в наш проект Construct 3 все это время. Чтобы начать, откройте файл manager.ts в любом текстовом редакторе!

Реализация призовой логики

Прежде чем мы начнем, мы должны импортировать транзакции из крипто библиотеки ARK. Для этого найдите:

Code:
import { Identities } from “@arkecosystem/crypto”;

Замените его на:

Code:
import { Identities, Transactions } from “@arkecosystem/crypto”;// Now, we’ll examine the relevant part of our existing generateState function to see what happens when a game is won or tied:if (outcome !== “ongoing”) {
    break;
}

Помните, что в случае ничьей значение переменной результата будет “tie”, и если кто-то выиграл, значение переменной результата будет 1 или 2, в зависимости от того, был ли победителем игрок 1 или игрок 2. В противном случае значение будет “ongoing”.

Из этого фрагмента кода мы видим на данный момент, что если значение исходной переменной не “ongoing”(т. е. игра выиграна или сыграна вничью), то наш цикл заканчивается, но больше ничего не происходит. Давайте продолжим и пересмотрим этот код сейчас для включения логики, чтобы платить нашим игрокам. Поскольку код выполняется только в том случае, если игра выиграна или сыграна вничью, мы должны это проверить Если это так, мы возвращаем ставку обоим игрокам. Если нет, это означает, что игрок выиграл игру, поэтому должен получить весь приз, который является суммой обеих ставок:

Code:
if (outcome !== "ongoing") {
    if (outcome === "tie") {
        this.pay(address, players, wager);
    } else {
        this.pay(address, players[outcome], wager * 2);
    }
    break;
}

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

ARK Core 2.6 представил широкий спектр полезных функций, которыми мы можем воспользоваться здесь. Первый - это nonces. Проще говоря, каждая транзакция из отправляющего кошелька должна иметь уникальное значение nonce и строго на единицу больше значения nonce самой последней транзакции, отправленной из кошелька. Мы можем использовать это, чтобы проверить значение nonce нашего игрового кошелька - если значение равно нулю, это означает, что мы еще никому не заплатили, поэтому мы должны это сделать. Если значение nonce не равно 0, мы уже заплатили за эту игру. Это предотвращает случай, когда игрокам платят несколько раз (например, когда вы перезапускаете свой плагин и состояние игры восстанавливается).

Вторая особенность - это мультиплатежи. Это означает, что в случае ничьей мы можем заплатить обоим игрокам за одну транзакцию. Это помогает уберечь от перегрузки сети, и поскольку существует только одна транзакция, это означает, что существует только один nonce.

Сопоставив все вместе, наша логика для функции оплаты выглядит следующим образом:

1.Если nonce кошелька не равен нулю, мы уже заплатили, поэтому мы должны выйти.
2.Мы получаем пароль для кошелька игры и его открытый ключ.
3.Если данные, переданные в функцию, представляют собой одну строку, мы генерируем стандартную транзакцию перевода на указанную сумму за вычетом комиссии за транзакцию и отправляем ее по адресу в строке.
4.Если предоставленные данные являются объектом, содержащим несколько адресов, мы генерируем транзакцию с несколькими платежами для обоих игроков с указанной суммой за вычетом комиссии за транзакцию.
5.Как только наша транзакция была сгенерирована, мы подписываем ее и транслируем в сеть.

Мы можем сделать это следующим образом:

Code:
private pay(sender: string, recipient: string | object, amount: number) {
    const wallet = app.resolvePlugin("database").walletManager.findById(sender);        if (wallet.nonce.toString() !== "0") {
        return;
    }    const passphrase = this.addresses[sender];
    const publicKey = Identities.PublicKey.fromPassphrase(passphrase);
    const fee = "1000000";
    const payAmount = (amount — parseInt(fee)).toString();
    let transaction;        if (typeof recipient === "string") {
        transaction = Transactions.BuilderFactory.transfer().nonce("1").senderPublicKey(publicKey).recipientId(recipient).fee(fee).amount(payAmount).vendorField("You won the game, congratulations!");
    } else {
        transaction = Transactions.BuilderFactory.multiPayment().nonce("1").senderPublicKey(publicKey).fee(fee).vendorField("The game was tied. Here is your wager!");
        transaction.addPayment(recipient[1], payAmount);
        transaction.addPayment(recipient[2], payAmount);
    }        const signedTransaction = transaction.sign(passphrase).build();
    app.resolvePlugin("p2p").getMonitor().broadcastTransactions([signedTransaction]);
}

Следующие шаги

Поздравляем, наша игра на блокчейне теперь может рассчитывать, присуждать, выплачивать призы или возвращать вступительные взносы в случае ничьей. Наша отдельная игра завершена! В заключительной части нашей серии руководств мы настроим нашу игру как плагин внутри ARK Desktop Wallet.

Если вы застряли в какой-то момент, обязательно ознакомьтесь с нашими документами в центре обучения ARK. Кроме того, наша команда и разработчики активны в Slack , поэтому не стесняйтесь обращаться к нам!

Проверьте предыдущие статьи из этой серии здесь:

     Часть первая: Как импортировать адрес кошелька ARK в ваше приложение
     Часть вторая: Создание бэкенда для вашего плагина
     Часть третья: Как заставить вашу игру работать с системой ставок
     Часть четвертая: Внедрение игровой логики в ваш плагин
legendary
Activity: 1610
Merit: 1026
Теперь добавьте еще одно дополнительное событие в событие Websocket -> On Text Message, чтобы проанализировать данные лобби. Выберите JSON, а затем Has Key. Введите «games», затем нажмите Готово. Нажмите «Добавить действие» для нашего вновь созданного дополнительного события и перейдите к «Система»> «Установить значение». Мы хотим установить для нашего объекта JSON значение JSON.get («games»). Нажмите Готово.

Мы добавим еще одно дополнительное событие для Websocket -> В текстовом сообщении, чтобы сохранить сетевой символ токена. Снова выберите JSON> Has Key. Введите «symbol», выберите «Готово», нажмите «Добавить действие» и выберите «Система»> «Установить значение». Установите для Symbol значение JSON.get («Symbol»).

Далее мы собираемся создать функцию для анализа данных нашего лобби. Щелкните правой кнопкой мыши пустую область и выберите «Добавить функцию». Назовите это ParseLobby. Вернитесь к нашему дополнительному событию для «games» и выберите «Добавить действие», затем «Функции»> «ParseLobby». Затем найдите наше предыдущее событие, где мы установили наш текст «Адрес действителен!» и добавьте еще одно действие к нему. Выберите «Система»> «Установить значение» и установите для переменной ValidatedAddress значение TextInput.Text. Теперь выберите «Добавить действие», затем «Функции»> «ParseLobby».


Наши модифицированные события

Найдите нашу функцию ParseLobby и выберите Добавить действие. Выберите Добавить сценарий. Теперь мы собираемся ввести наш код, чтобы проанализировать список лобби и заполнить наши фреймы:

Code:
const games = JSON.parse(runtime.globalVars.JSON);
const newGames = [];
const existingGames = [];
const ourGames = [];for (const address of Object.keys(games)) {
    const game = games[address];        if (game.players[2]) {
        existingGames.push({ address, game });                if (game.players[1] === runtime.globalVars.ValidatedAddress || game.players[2] === runtime.globalVars.ValidatedAddress)
            ourGames.push({ address, game });
        }
    } else {
        newGames.push({ address, game });
    }
}let html = "";for (const game of newGames) {
    const wager = (game.game.wager / 100000000);
    html += "
New game by " + game.game.players[1] + " for " + wager + runtime.globalVars.Symbol + " (Join)
";
}document.getElementById("NewIframe").contentWindow.document.body.innerHTML = html;
html = "";for (const game of existingGames) {
    const wager = game.game.wager / 100000000;
    html += "
Game between " + game.game.players[1] + " and " + game.game.players[2] + " for " + wager + runtime.globalVars.Symbol + "
";
}document.getElementById("ExistingIframe").contentWindow.document.body.innerHTML = html;
html = "";for (const game of ourGames) {
    const wager = game.game.wager / 100000000;
    html += "
Game between " + (game.game.players[1] === runtime.globalVars.ValidatedAddress ? "you" : game.game.players[1]) + " and " + (game.game.players[2] === runtime.globalVars.ValidatedAddress ? "you" : game.game.players[2]) + " for " + wager + runtime.globalVars.Symbol + "
";
}document.getElementById("OurIframe").contentWindow.document.body.innerHTML = html;

Вы можете спросить, что  делает код? Он будет проходить через все наши игры, и если будет два игрока, то это уже существующая игра, в противном случае это новая игра, и будет показана ссылка для автоматической отправки транзакции, чтобы присоединиться к игре, используя  ark: URI, про которую мы писали в последнем уроке. Если адрес совпадает с нашим, он добавит игру в третью колонку для удобства идентификации. Конечно, вы можете поиграть с HTML-кодом и добавить стили к элементам div внутри наших фреймов, чтобы сделать его по-настоящему популярным!

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

Следующие шаги

Поздравляем с окончанием третьего урока! Сегодня мы узнали, как анализировать блокчейн для создания лобби и сопоставления ставок, при этом данные автоматически обновляются в клиенте без обновления вручную. В следующем уроке мы будем играть с полем «smartbridge field», также известным как vendor field, чтобы реализовать пошаговую игровую логику, чтобы сделать нашу игру рабочей.

Если вы застряли в какой-то момент, обязательно ознакомьтесь с нашими документами в центре обучения ARK. Кроме того, наша команда и разработчики активны в Slack , поэтому не стесняйтесь обращаться к нам!
legendary
Activity: 1610
Merit: 1026
Это будет проходить через все наши сгенерированные адреса и вызывать нашу еще не написанную функцию generateState для генерации их игрового состояния при первой загрузке нашего плагина.

Затем найдите, где мы слушаем входящие транзакции, которые мы написали в нашем последнем уроке:

Code:
emitter.on(ApplicationEvents.TransactionApplied, transaction => {
    if (this.addresses[transaction.recipientId]) {
        for (const websocket of server.clients) {
            // @ts-ignore
            if (websocket.readyState === WebSocket.OPEN && websocket.address === transaction.recipientId) {
                websocket.send(JSON.stringify({ transaction }));
            }
        }
    }
});

Во-первых, в верхней строке измените транзакцию на асинхронную, чтобы наша функция была асинхронной. Затем посмотрите строку for (const websocket of server.clients) Непосредственно перед этой строкой добавьте это, чтобы восстановить состояние любого игрового адреса, который получает новую транзакцию, как только она записывается в базу данных блокчейна:

Code:
while (!(await app.resolvePlugin(“database”).transactionsBusinessRepository.findById(transaction.id))) {
    await delay(100);
}await this.generateState(transaction.recipientId);

Теперь пришло время написать эту неуловимую функцию generateState. Найдите наш блок кода, в котором мы написали функцию generateAddress, и непосредственно под этим блоком мы напишем наш новый код generateState:

Code:
private async generateState(address: string) {
    const database = app.resolvePlugin("database");
    const publicKey = Identities.PublicKey.fromPassphrase(this.addresses[address]);        const transactions: any[] = await Promise.all(
        (await database.transactionsBusinessRepository.search({
            limit: 0,
            walletAddress: address,
            publicKey
        })).rows.map(async transaction => ({
            amount: transaction.amount,
            recipientId: transaction.recipientId,
            senderId: Identities.Address.fromPublicKey(transaction.senderPublicKey, app.getConfig().get("network.pubKeyHash")),
            timestamp: (await database.blocksBusinessRepository.findById(transaction.blockId)).timestamp,
            vendorField: transaction.vendorField ? transaction.vendorField.toString().trim().toUpperCase() : null
        })
    ));        transactions.sort((a: any, b: any) => (a.timestamp > b.timestamp) ? 1 : ((b.timestamp > a.timestamp) ? -1 : 0));        const players = { 1: null, 2: null };
    let wager = 0;
    for (const transaction of transactions) {
        if (transaction.senderId !== address && transaction.amount >= 10000000) {
            players[1] = transaction.senderId;
            wager = transaction.amount;
            break;
        }
    }        if (!players[1]) {
        return;
    }        for (const transaction of transactions) {
        if (transaction.senderId !== address && transaction.senderId !== players[1] && transaction.amount === wager) {
            players[2] = transaction.senderId;
            break;
        }
    }        this.gameStates[address] = { players, wager };
}

Это была большая работа за короткий промежуток времени, поэтому давайте разберемся с тем, что мы только что сделали. Мы передаем сгенерированный игровой адрес в эту функцию и преобразуем соответствующую парольную фразу в открытый ключ, который нам необходим для поиска всех входящих и исходящих транзакций с адреса кошелька. Мы извлекаем сумму, кошелек получателя, кошелек отправителя, отметку времени и сообщение smartbridge для каждой транзакции и сортируем их в хронологическом порядке. Затем мы перебираем транзакции от самых старых до самых новых, чтобы найти первую входящую транзакцию стоимостью не менее 1 ARK; сумма становится ставкой, а адрес игрока распределяется как игрок 1. Если соответствующий адрес не найден, игра недействительна, поэтому мы отменяем. В противном случае, мы повторяем транзакции, чтобы найти другого игрока, который соответствует ставке. Этот адрес становится игроком 2. Затем мы добавляем адреса и ставки игроков в наш объект gameStates.
Передача списка игр клиенту

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

Найдите:
Code:
websocket.send(networkData);

Сразу после этого добавьте:

Code:
websocket.send(JSON.stringify({ games: JSON.stringify(this.gameStates) }));
// This will send all our game states to the client as soon as it connects.// Lastly, find:
for (const websocket of server.clients) {
    // @ts-ignore
    if (websocket.readyState === WebSocket.OPEN && websocket.address === transaction.recipientId) {
        websocket.send(JSON.stringify({ transaction }));
    }
}

И заменить его на:

Code:
const state = JSON.stringify({ games: JSON.stringify(this.gameStates) });for (const websocket of server.clients) {
    if (websocket.readyState === WebSocket.OPEN) {
        websocket.send(state);                // @ts-ignore
        if (websocket.address === transaction.recipientId) {
            websocket.send(JSON.stringify({ transaction }));
        }
    }
}

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

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

Фильтрация игр по их состоянию

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

Перейдите в Layout Editor для Layout 1 и добавьте 3 новых объекта iframe. Назовите их NewIframe, ExistingIframe и OurIframe. В первом кадре будут перечислены новые игры, ожидающие соперника, во втором - все игры с соответствующими ставками, а в третьем - игры, в которых участвует наш адрес. Для каждого добавленного объекта iframe установите идентификатор, соответствующий назовите и удалите значения URL по умолчанию.

Перейдите к нашему Листу событий 1 и щелкните правой кнопкой мыши пустую область нашего листа событий и выберите Добавить глобальную переменную. Назовите это «JSON», который должен быть String. Повторите это, но назовите нашу следующую глобальную переменную «ValidatedAddress». Сделайте это еще раз, но назовите нашу новую переменную «Symbol».


Глобальные переменные должны выглядеть так в верхней части таблицы событий
legendary
Activity: 1610
Merit: 1026
Перевод. Оригинальная статья Launching HTML5 Games In The ARK Desktop Wallet — Part Three
https://blog.ark.io/launching-html5-games-in-the-ark-desktop-wallet-part-three-74fc5398b96f


Запуск HTML5 игр в ARK Desktop Wallet - часть третья

Добро пожаловать в третий урок из нашей серии о запуске игры HTML5 в ARK Desktop Wallet! Эта серия предназначена для разработчиков всех уровней квалификации. Цель этой серии - преобразовать игру HTML5 в полноценный плагин для ARK Desktop Wallet.

В предыдущих частях (Первая часть и Вторая часть) мы настраивали базовый игровой клиент, используя Construct 3, который взаимодействует с нашим собственным плагином ARK Core для проверки адресов и отправки и получения транзакций в блокчейне.

Теперь пришло время заставить игру работать со ставками и создать лобби для запуска игр и просмотра уже существующих! Но давайте не будем забегать вперед, реальная игровая логика появится в следующей части этой серии, поскольку мы все еще закладываем основы для взаимодействия с сетью и блокчейном. Хорошая новость заключается в том, что код, который мы написали в этих предыдущих частях, может быть повторно использован в будущих проектах, так что у вас будет прочная база для взаимодействия между вашими будущими игровыми клиентами и ARK Core, без необходимости переделывать всю работу снова.

Как и в прошлый раз, мы собираемся сосредоточиться на нашем плагине ARK Core, а затем расширить наш проект Construct 3 для взаимодействия с ним. К концу этого урока мы сможем:
Отслеживать все сгенерированные игровые адреса и сохраняйте их на диск, чтобы наши ставки и игры не терялись при перезапуске Core.
Записать ставку и убедиться, что партнер платит правильную сумму.
Передать список игр клиенту.
Фильтрация игр по их состоянию, т. е. Ожидают ли они партнера, завершены, или один из участников является нашим собственным подтвержденным адресом, чтобы отличать наши собственные игры.

Итак, давайте не будем тратить больше времени - откройте файл manager.ts в вашем любимом текстовом редакторе, и мы приступим к работе!
Отслеживание всех сгенерированных игровых адресов для сохранения

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

Есть разные возможности. Например, вы можете захотеть использовать базу данных, будь то PostgreSQL, MySQL, SQLite3 или другие, но мы собираемся упростить задачу и использовать уже созданную библиотеку под названием FluiDB. Мы можем просто создать новый объект FluiDB для хранения наших игровых адресов, и он будет автоматически и прозрачно загружать и сохранять данные на диск для постоянного хранения, не беспокоясь о написании беспорядочных SQL-запросов или изобретении нашей собственной структуры данных.

Давайте импортируем FluiDB в наш проект, выполнив следующую команду на нашем сервере для установки библиотеки:
Code:
lerna add fluidb — dev
Теперь мы импортируем связь в наш плагин, добавив следующие строки в начало нашего файла manager.ts:
Code:
import delay from "delay";
import FluiDB from "fluidb";// Replace our previous implementation with FluiDB. Find:
private addresses = {};// Replace it with:
private addresses = new FluiDB(`${process.env.CORE_PATH_DATA}/generated-addresses`);
private gameStates = {};

Мы это сделали! Теперь это автоматически сохранит все наши сгенерированные адреса и парольные фразы в файле с именем generate-address.json в нашей папке данных Core, и будет прозрачно загружать их обратно в наш объект адресов при каждом перезапуске Core. Это также импортировало другой пакет, delay, и объявило другую переменную, gameStates, в ожидании нашего следующего раздела.

Записать ставку и убедиться, что наш партнер ей соответствует

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

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

Найдите нашу строку здесь, где мы объявляем нашу функцию запуска:
Code:
public start(options: any) {// Make it asynchronous by adding the async keyword, so it looks like this:
public async start(options: any) {

Находим
Code:
const networkData = JSON.stringify({ networkVersion: config.get(“network.pubKeyHash”) });

Меняем код
Code:
const networkData = JSON.stringify({
    networkVersion: config.get("network.pubKeyHash"),
    symbol: config.get("network.client.symbol")
});//On the next line, add the following block of code:
for (const address of Object.keys(this.addresses)) {
    this.generateState(address);
}

legendary
Activity: 1708
Merit: 1615
#SWGT CERTIK Audited
Прослушивайте входящие транзакции
Последняя часть нашего основного плагина для этой части руководства будет прослушивать входящие транзакции. Если получающий адрес совпадает с одним из сгенерированных ранее адресов, мы отправим его данные обратно в наше приложение Construct 3 через WebSocket.
Этот кусок кода будет идти сразу над второй строкой catch в нашем методе start:
Code:
const emitter = app.resolvePlugin("event-emitter"); emitter.on(ApplicationEvents.TransactionApplied, transaction => {
    if (this.addresses[transaction.recipientId]) {
        for (const websocket of server.clients) {
            // @ts-ignore
            if (websocket.readyState === WebSocket.OPEN && websocket.address === transaction.recipientId) {
                websocket.send(JSON.stringify({ transaction }));
            }
        }
    }
});

Чтобы закончить, нам нужен только один финальный импорт в верхней части кода для ApplicationEvents, которые мы использовали:
Code:
import { ApplicationEvents } from “@arkecosystem/core-event-emitter”;

К этому моменту мы закончили с нашим плагином Core для этой части урока! Скомпилируйте его с настройкой плагина, перезапустите Core и перейдите к Construct 3, где мы будем взаимодействовать с нашим WebSocket. Откройте проект, который мы создали в последнем уроке, переключитесь на Layout 1, щелкните правой кнопкой мыши и вставьте новый объект. Добавьте WebSocket. Повторите процесс, добавив объект Browser, объект JSON и другую кнопку, которая будет использоваться для запуска процесса генерации адреса.

Перейдите на лист событий 1 и добавьте новое событие. Разверните до System и затем On the layout. Мы хотим добавить действие для WebSocket для подключения. Введите URL в формате wss: //X.X.X.X: 10000 / где X.X.X.X - ваш базовый IP-адрес. Обратите внимание, что для этого требуется соединение HTTPS, поэтому вам может потребоваться использовать бесплатную службу, такую ​​как CloudFlare, или использовать собственный сертификат SSL с обратным прокси-сервером, таким как Nginx.

Добавьте другое событие, на этот раз прослушивая событие Websocket -> On Text Message. Для соответствующего действия выберите JSON -> Parse. Введите WebSocket.MessageText для строки JSON.

Теперь мы хотим добавить несколько вложенных событий в событие Websocket -> On Text Message для обработки полученных нами данных WebSocket. Выберите JSON, а затем KEY. Введите «транзакция», затем добавьте новое действие. Это будет запущено, когда мы получим новую транзакцию. Сейчас, чтобы доказать, что это работает, мы просто собираемся отобразить данные транзакции в окне предупреждения в браузере. Выберите Browser, затем Alert. Введите JSON.GetAsBeautifiedString («transaction»).

Добавьте другое вспомогательное событие и выберите JSON, а затем Has Key. Введите «networkVersion» на этот раз. Это будет использоваться для установки  версии сети, чтобы наше приложение правильно проверяло адреса в зависимости от сети того партнера, к которому мы подключены. Наше соответствующее действие должно быть System -> Set Value.

Убедитесь, что переменная имеет значение networkVersion, и установите значение JSON.Get («networkVersion»).

Теперь мы должны проверить вновь сгенерированный адрес, показать его пользователю и разрешить пользователю отправлять транзакции через Desktop Wallet. Чтобы продолжить, мы должны добавить еще одно дополнительное событие. Это снова JSON -> Имеет ключ. Введите «адрес» и добавьте новое действие браузера. Выберите Alert и введите. Нажмите «ОК», чтобы отправить транзакцию в JSON.Get («адрес»). Добавьте еще одно действие для этого события, на этот раз для Браузер -> Перейти к URL. В качестве URL-адреса мы вводим «ark:» и JSON.Get («адрес»), который автоматически откроет рабочий стол и предварительно заполнит транзакцию, которая будет отправлена ​​на вновь созданный адрес.
Наконец, мы собираемся подключить нашу новую кнопку для запуска этого действия генерации адреса. Добавьте событие, выбрав Button2 (так как это наша вторая кнопка), а затем нажал кнопку «Вкл». Мы собираемся добавить действие для отправки сообщения через WebSocket, чтобы запустить процесс создания адреса, поэтому выберите WebSocket, а затем «Отправить текст». Текст, который мы отправим, будет “{“”action””: “”new””}” ».

Теперь мы закончили! Наш лист событий должен выглядеть примерно так:


Если вы используете плагин Core в сети разработки ARK, вы должны обнаружить, что он теперь принимает только адреса Devnet. Нажав вновь добавленную кнопку, вы получите сообщение с новым сгенерированным адресом, после чего откроется ARK Desktop Wallet для автоматической отправки транзакции на этот адрес:



Теперь, если мы отправим транзакцию на этот адрес, наше приложение Construct 3 автоматически получит ее и покажет нам данные:


Поздравляем с окончанием урока! Это может показаться малым, но мы многого достигли! Мы настроили наш базовый плагин Core, сделали сервер WebSocket, и теперь мы знаем, как генерировать новые адреса, отправлять и получать транзакции между нашим приложением и сетью и динамически проверять адреса на основе сети однорангового узла.

Следующие шаги
Вот и все для второй части этого урока. На нашей следующей сессии мы заставим игру работать с системой ставок и создадим лобби для запуска игр и просмотра уже существующих!
Если вы застряли в какой-то момент, обязательно ознакомьтесь с нашими документами в центре обучения ARK центре обучения ARK. Кроме того, наша команда и разработчики активны в Slack, поэтому не стесняйтесь обращаться к нам!
legendary
Activity: 1708
Merit: 1615
#SWGT CERTIK Audited
Перевод
https://blog.ark.io/launching-html5-games-in-the-ark-desktop-wallet-part-two-d07b6620bd46
Ray.Alva

Запуск HTML5 игр в ARK Desktop Wallet - часть вторая


Добро пожаловать во второй урок из нашей серии, посвященной запуску HTML5 игр в ARK Desktop Wallet! Эта серия предназначена для разработчиков всех уровней квалификации. Цель этой серии - преобразовать игру HTML5 в полноценный плагин ARK Desktop Wallet. Первый набор руководств объяснит, как взаимодействовать с блокчейном ARK в автономной среде HTML5, прежде чем, наконец, перепрыгнуть в ARK Desktop Wallet.

Мы остановились в прошлый раз в прошлый раз на автономном приложении Construct 3 (  https://editor.construct.net/ ), которое позволяет нам удостовериться, что указанный адрес действителен в публичной сети ARK. Теперь пришло время развить это, чтобы работать с любой сетью на базе ARK по нашему выбору и начать создавать серверную часть нашей игры.

В оставшейся части этого учебного цикла мы сосредоточимся на создании серверной части нашей игры и использовании Connect 4, пошаговой блокчейн-игры в качестве нашего текущего примера и шаблона. Мы позволим игроку начать игру, установив ставку, и как только ставка будет получена, игра начнется. Мы будем использовать стандартную доску 7 x 6, и каждый игрок по очереди выберет колонку и вставит свой диск от 1 до 7. Если игрок выстроит в линию 4 диска по вертикали, горизонтали или диагонали, он получит приз ; если игра заканчивается ничьей, оба игрока получают обратно свой вступительный взнос. Для простоты мы будем использовать поле Smartbridge от ARK, чтобы выбрать выбранную колонку на доске от 1 до 7. Если вы хотите использовать более продвинутый подход, вы можете рассмотреть возможность совершения пользовательских транзакций с GTI на собственной мостовой цепочке, чтобы сделать эту игру по-настоящему децентрализовано.

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

ПРЕДУПРЕЖДЕНИЕ: Прежде чем мы пойдем дальше, проверьтеARK Learning Hub  , чтобы понять, как создать ваш первый модуль Core. Следуйте инструкциям и используйте шаблон  стартового модуля. Это будет основой для остальной части урока.

Теперь, когда вы настроили свой начальный модуль, давайте перечислим наши цели относительно того, что мы хотим, чтобы наш плагин Core сделал к концу этого урока.
Начнем:
1.Настройте сервер WebSocket, чтобы наше приложение Construct 3 и плагин Core могли общаться друг с другом;
2.Отправляйте  версию сети (о которой мы говорили в последнем уроке) всякий раз, когда приложение подключается к серверу, чтобы оно знало формат адреса для проверки;
3. Создайте новый адрес ARK для приема транзакций;
4. Проверьте входящие транзакции, отправленные на этот адрес.

Давайте уделим некоторое время каждому из разделов выше. Весь наш код будет записан в defaults.ts и manager.ts, поэтому откройте их в своем любимом текстовом редакторе и начнем!
Настройка сервера WebSocket
Во-первых, мы хотим настроить сервер WebSocket. Мы будем использовать WebSockets, потому что он обеспечивает простую двунаправленную связь между нашим плагином и приложением Construct 3. WebSockets связываются с хостом и портом, и для начала мы определим их в defaults.ts. Замените содержимое этого файла следующим:

Code:
export const defaults = {
    enabled: true,
    host: "0.0.0.0",
    port: 10000
};

Мы используем хост 0.0.0.0, что означает, что мы будем принимать подключения к любому из IP-адресов на нашем сервере, и мы будем соединяться через порт 10000. Сохраните этот файл и закройте его, так как все наши оставшиеся изменения будут внесены в менеджер .ts.

Для этого мы сначала импортируем зависимость ws, добавив следующую строку в начало нашего файла:
Code:
import * as WebSocket from “ws”;

Теперь мы хотим запустить наш сервер WebSocket при запуске нашего плагина. Возможно, вы уже заметили метод start в manager.ts, где мы и запустим наш сервер:
Code:
public start(options: any) {
    this.logger.info("Initialization of dApp");
}

Давайте изменим это, чтобы запустить наш сервер WebSocket и напечатать более подробное сообщение:
Code:
public start(options: any) {
    try {
        const server = new WebSocket.Server({ host: options.host, port: options.port });
        this.logger.info(`Connect 4 WebSocket server listening on ws://${options.host}:${options.port}`);
    } catch (error) {
        this.logger.error(`Connect 4 WebSocket server could not start: ${error.message}`);
    }
}

Что это делает? Он запускает сервер WebSocket, используя значения хоста и порта, которые мы ранее определили в defaults.ts, и печатает сообщение в наших журналах, чтобы подтвердить, что сервер успешно запущен, или, в случае сбоя, он объяснит, что пошло не так.
Отправка  версии сети

Мы хотим отправить версию сети любому клиенту, который обращается к нашему WebSocket, как только он подключится. Для этого мы прослушиваем событие соединения с сервера WebSocket, которое срабатывает при установлении нового соединения, а затем отправляем  версию сети новому соединению. Добавьте следующий код после строки this.logger.info:

Code:
const config = app.getConfig();
const networkData = JSON.stringify({ networkVersion: config.get("network.pubKeyHash") });

server.on("connection", websocket => {
    websocket.send(networkData);
});

На этом этапе вы можете запустить настройку плагина, перезапустить ядро Core и проверить журналы. Вы должны увидеть что-то вроде этого:
Code:
1|ark-relay | [2020–02–17 19:00:00.000] INFO : Connect 4 WebSocket server listening on ws://0.0.0.0:10000

Мы можем проверить, работает ли WebSocket, перейдя по адресу http://www.websocket.org/echo.html и введя ws: // XXXX: 10000 (где XXXX - IP-адрес вашего сервера, на котором работает наш плагин Core) и нажимая Connect. Если вы выполнили действия, описанные выше, вы должны увидеть, что версия сети появится в окне журнала:



Генерация нового ARK-адреса для приема транзакций
Нам нужен наш плагин для генерации нового адреса для получения ставок и обработки сообщений Smartbridge для обновления нашего игрового состояния. Для этого наше приложение Construct 3 отправит на сервер сообщение {action: «new»}, которое запустит это действие. Наш плагин Core должен прослушать это сообщение и действовать в соответствии с ним, поэтому мы добавим следующий код сразу после строки websocket.send (networkData) выше:

Code:
websocket.on("message", message => {
    try {
        const data = JSON.parse(message.toString());
        if (data.action === "new") {
            const { address, passphrase } = this.generateAddress();
            this.addresses[address] = passphrase;
            // @ts-ignore
            websocket.address = address;
            websocket.send(JSON.stringify({ address }));
        }
    } catch (error) {
        this.logger.error(error.stack);
    }
});

Вы увидите, что мы используем новый метод generateAddress, поэтому мы должны написать код и для этого. Вставьте это ниже конца нашего метода start и перед методом stop:
Code:
private generateAddress() {
    const passphrase = generateMnemonic();
    const address = Identities.Address.fromPassphrase(passphrase);
    return { address, passphrase };
}

Нам также нужно добавить несколько импортов в начало нашего кода, чтобы получить доступ к этим новым методам:
Code:
import { generateMnemonic } from “bip39”;
import { Identities } from “@arkecosystem/crypto”;
// Lastly we add a new addresses private variable immediately above // the private readonly logger line:
private addresses = {};

Это довольно большой код, поэтому давайте разберем его. Мы прослушиваем любые входящие сообщения через WebSocket, которые содержат {action: «new»}, сигнализирующий, что наше приложение Construct 3 хочет создать новый адрес для новой игры. Это вызывает наш новый метод generateAddress для внутреннего создания новой парольной фразы кошелька и преобразования ее в адрес. Теперь он хранится в объекте адресов, который отслеживает все адреса, созданные во время этого сеанса, которые будут использоваться для прослушивания входящих транзакций.
legendary
Activity: 1610
Merit: 1026
продолжение
Теперь нам нужно сказать, что делать, когда кто-то нажимает кнопку. Но что именно мы хотим от этого? Адреса должны быть длиной 34 символа, начинаться с правильного символа для нашей сети, состоять только из символов base58 и проходить проверку контрольной суммы. К счастью, скрипт bs58check, который мы импортировали ранее, обрабатывает большую часть этого за нас. Мы будем использовать публичную сеть ARK, поэтому мы знаем, что наша сетевая версия - 23.

Начнем с создания переменной для хранения сетевой версии. Щелкните правой кнопкой мыши наш лист событий и выберите Добавить глобальную переменную. Назовите его networkVersion с начальным значением 23.

Мы создадим функцию для проверки адреса. Щелкните правой кнопкой мыши в любом месте листа событий и выберите «Добавить функцию». Назовите его validateAddress и установите тип возвращаемого значения Number. Нажмите OK, затем щелкните правой кнопкой мыши нашу новую функцию и добавьте параметр. Назовите это адресом, который является Строкой. Теперь щелкните правой кнопкой мыши на Добавить действие для нашей функции и выберите Добавить сценарий. Теперь мы можем наконец написать немного JavaScript!

Code:
if (localVars.address.length === 34) {try {const networkVersion = bs58check.decode(localVars.address).readUInt8(0);if (networkVersion === runtime.globalVars.networkVersion) {runtime.setReturnValue(1);}} catch (error) {// the address is invalid}}

Давайте разберемся с этим. По умолчанию функция вернет ноль. Если адрес составляет 34 символа, он выполнит bs58check.decode, который выдаст ошибку и выйдет из функции, если адрес содержит недопустимые символы или контрольная сумма не пройдена. В противном случае мы проверяем, соответствует ли сетевая версия публичной сети ARK. Если это так, мы возвращаем значение 1. Проще говоря, если адрес проходит наши проверки, функция возвращает 1, в противном случае возвращает 0.

Теперь мы включим нашу функцию! Мы хотим, чтобы он запускался при каждом нажатии нашей кнопки. Нажмите «Добавить» рядом с нашим событием «По нажатию» и «Добавить подсобытие». Прокрутите вниз до System и сравните два значения. По сути, мы хотим проверить, возвращает ли наша функция 1 или нет. Итак, наше первое значение должно быть Functions.validateAddress (TextInput.Text), а наше второе значение должно быть 1.



Почти готово! Мы просто должны сказать ему, что делать, если функция проходит и не работает. Нажмите кнопку Добавить действие для нашего сравнения, дважды щелкните наш текстовый объект и выберите Установить текст. Введите «Адрес действителен!» и выберите ОК. Теперь для случая сбоя: нажмите кнопку Добавить ... рядом с нашим новым действием Установить текст и выберите Добавить еще. Нажмите «Добавить действие для нашего другого случая», дважды щелкните наш текстовый объект и выберите «Задать текст». Введите «Адрес недействителен» и нажмите ОК.



Теперь мы можем проверить наше творение, щелкнув треугольник в строке меню. Попробуйте ввести действительный адрес ARK Public Network и нажмите кнопку, затем попробуйте неверный. Вернитесь в исходный код и измените переменную networkVersion с 23 на 30 и повторите попытку с адресом Devnet. Теперь все в порядке, и теперь вы сможете определить, является ли адрес действительным в публичной сети ARK или в сети разработчиков ARK!
Следующие шаги

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

Если вы отстали в какой-то момент, обязательно ознакомьтесь с нашими документами в центре обучения ARK. Кроме того, наша команда и разработчики активны в Slack, поэтому не стесняйтесь обращаться к нам!
https://learn.ark.dev/core-getting-started/setting-up-your-development-environment
https://ark.io/slack
legendary
Activity: 1610
Merit: 1026
Перевод. Оригинальная статья Launching HTML5 Games In The ARK Desktop Wallet — Part One
https://blog.ark.io/launching-html5-games-in-the-ark-desktop-wallet-part-one-b26fd444f0d79c42

Запуск HTML5 игр в настольном кошельке ARK - часть первая


Добро пожаловать в первый урок из нашей серии, посвященный запуску игр на HTML5 в ARK Desktop Wallet! Эта серия предназначена для разработчиков всех уровней. Цель этой серии - преобразовать игрs HTML5 в полноценный плагин ARK Desktop Wallet. Первое руководство объяснит, как взаимодействовать с блокчейном в автономной среде HTML5, прежде чем, наконец, перейти в ARK Desktop Wallet.

На первый взгляд, этот учебник будет разбит на следующие части:

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

Прежде чем мы начнем, нужно помнить одну вещь: эти учебные пособия направлены на запуск HTML5-игры в ARK Desktop Wallet. Эти учебные пособия не предназначены для обучения разработчиков, как создавать игры. Однако, как только ваша игра будет готова, мы будем рады поддержать ее в ARK Desktop Wallet. Итак, давайте  начнем с импорта адреса кошелька в вашу игру!

Импортирование адреса кошелька в вашу игру

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

Мы будем использовать бесплатный  движок Construct 3 - среду разработки игры «укажи и щелкни» - чтобы создать нашу простую игру HTML5, так что зайди туда и начни
новый проект.
https://editor.construct.net/

Это кому-нибудь знакомо? Это Сапер… Первая игра ARK для блокчейнов «игрок против игрока»!

К сожалению, на момент написания ARK JavaScript SDK не был полностью совместим с играми HTML5 из коробки, поэтому мы будем использовать альтернативу bs58check для проверки адресов. Шаги для создания нашей альтернативы описаны ниже, но если вы предпочитаете пропустить это, вы можете использовать готовую версию, которую мы обсудим через секунду. Если вы хотите собрать его самостоятельно, убедитесь, что у вас установлены NodeJS и npm, а затем выполните:
Code:
npm install -g browserify uglify-jsnpm 
install bs58check
browserify — standalone bs58check -r bs58check | uglifyjs > bs58check.min.js
Затем мы импортируем наш файл bs58check.min.js в наш проект Construct 3, чтобы игра могла его использовать. Это действительно просто - просто щелкните правой кнопкой мыши «Сценарии» в правой верхней панели, выберите «Импорт сценариев» и перетащите файл bs58check.min.js в окно. Нажмите Импорт, и все готово!


Что делает адрес кошелька ARK действительным?

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

Каждый адрес должен быть ровно из 34 символов, а в случае публичной сети ARK каждый адрес начинается с буквы A; и наоборот, адреса в ARK Development Network начинаются с буквы D, а бриджченйны могут использовать свой собственный символ. Этот первый символ связан с сетевой версией - запомните, мы вернемся к нему через позже. Символы, используемые в адресе, известны как base58, который представляет собой группу из 58 буквенно-цифровых символов, которые легко различить для минимизации риска путаницы, например, 0 (ноль) и O (верхний регистр o) выглядят одинаково, поэтому они исключаются ; кроме того, I (прописные буквы i) и l (строчные буквы L) исключаются из набора символов по той же причине. Наконец, адрес включает контрольную сумму, чтобы убедиться, что остальная часть адреса была введена правильно, без опечаток.

Итак, помните, как первый символ адреса ARK Public Network - A, а ARK Development Network - D? Это происходит от того, что называется сетевой версией, и каждый блокчейн может иметь различную сетевую версию, которая определяет первый символ всех адресов кошелька в этой сети. В случае, если вам интересно - и вам это понадобится позже, - сетевая версия для ARK Public Network - 23, а сетевая версия для ARK Development Network - 30.

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

Добавление адреса кошелька ARK в вашу игру

Давайте начнем с добавления некоторых объектов в наш макет. В нашем примере мы собираемся добавить поле ввода текста для ввода пользователем своего адреса, кнопку для подтверждения введенного адреса и текстовое отображение, чтобы сообщить нам, является ли адрес действительным. Дважды щелкните «Макет 1» в правой верхней панели, затем щелкните правой кнопкой мыши пустой холст и выберите «Вставить новый объект». Дважды щелкните ввод текста и поместите его на макет, где вы хотите, чтобы он появился. Повторите это, чтобы добавить объекты Button и Text тоже. Не стесняйтесь настраивать стиль объектов так, как вам нравится, и если вы чувствуете себя креативным, добавьте несколько спрайтов и фоновое изображение, чтобы оживить ваш макет.



Сейчас мы собираемся погрузиться в Лист событий, и именно здесь происходит вся магия. Конструкция 3 основана на событиях, то есть реагирует на ситуации, возникающие в течение жизненного цикла игры. В нашем случае это событие, когда пользователь нажимает нашу кнопку. Дважды щелкните «Лист событий 1» и выберите «Добавить событие». Дважды щелкните нашу кнопку и выберите событие «По нажатию». Он будет выделен желтым цветом, поскольку это обычное событие.
staff
Activity: 3430
Merit: 3971
Crypto Swap Exchange
legendary
Activity: 1708
Merit: 1615
#SWGT CERTIK Audited
После внесения вышеуказанных изменений вы готовы запустить пробную версию! ARK Messenger - это инициатива сообщества, в которой каждый может принять участие. Если вы хотите внести свой вклад, не стесняйтесь отправлять задавать вопросы/ Скачать  клиент Messenger и Core репозитории.

Развитие с АРК


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

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

Custom Transactions

Для создания транзакций, которые станут основой ARK Messenger, необходимо внести изменения в некоторые из существующих типов транзакций в ARK Core. Для этого ARK упростил внесение этих изменений через наш универсальный интерфейс транзакций (GTI). Цель GTI - предоставить разработчикам простой способ внедрения и включения новых типов транзакций в ядро ​​ARK без необходимости изменения больших частей ядра ARK.

Если вы хотите узнать больше о разработке пользовательских типов транзакций с помощью GTI, тогда читайте здесь:
https://blog.ark.io/an-introduction-to-blockchain-application-development-part-2-2-909b4984bae

ARK Deployer

Используя ARK Deployer, автономный блокчейн ARK Messenger был создан быстро и эффективно. Созданный блокчейн также был адаптирован для удовлетворения потребностей этого конкретного PoC. ARK Deployer позволяет любому в состоянии подготовить, настроить и развернуть блокчейн всего за несколько простых шагов.

Если вы хотите поближе познакомиться с тем, как это все возможно, пожалуйста, ознакомьтесь с документацией по ARK Deployer здесь:
https://deployer.ark.dev/

Финансирование ARK Grants

В случае, если вы не слышали, ARK Messenger PoC полностью финансировался программой ARK Grants. ARK Grants - это программа поощрения разработчиков, предназначенная для роста сообщества разработчиков. Разработчики могут получить финансирование для создания PoC на основе ARK, плагинов и готовых приложений. Программа поддерживается 1 миллионом ARK и в настоящее время принимает заявки!

Узнайте о принципах ARK Grants и порядке подачи заявок на http://ark.io/grants


Спасибо, что присоединились к нам! Если у вас есть какие-либо вопросы, обязательно ознакомьтесь с нашими документами в центре
обучения ARK. Кроме того, наша команда и разработчики сообщества активны в Slack, поэтому не стесняйтесь обращаться к нам!

ARK Messenger Учебное пособие

Если вы пропустили другие записи в блоге ARK Messenger Tutorial, вы можете прочитать их, перейдя по ссылкам ниже:

Первая часть
Вторая часть
Часть третья (вы сейчас ее читайте  Smiley )
legendary
Activity: 1708
Merit: 1615
#SWGT CERTIK Audited
Перевод
https://blog.ark.io/ark-messenger-tutorial-part-three-e2618fdf2434
Ray.Alva

Руководство по ARK Messenger — 3 часть



Добро пожаловать на заключительную часть нашей серия руководств по ARK Messenger Proof-of-Concept (PoC). В первой части мы создали среду разработки и развернули собственную настраиваемую мостовую цепочку. Во второй части мы создали пользовательскую транзакцию и протестировали ее. Это руководство было написано частично с документацией, предоставленной делегатом Lemii в рамках его работы  по ARK Messenger Proof-of-Concept, которая финансировалась ARK Grants Program.

Теперь, когда мы достигли завершения этой серии, пришло время, наконец, запустить Proof-of-Concept. После запуска PoC мы расскажем об уникальных способах использования ARK в ARK Messenger PoC.

Запуск PoC

Мостовая цепочка, поддерживающая ARK Messenger, была запущена с использованием ARK Deployer. С точки зрения разработки, ARK Deployer - это один из самых простых способов запуска блокчейна для вашего проекта. Однако для создания ARK Messenger PoC были сделаны некоторые конфигурации, чтобы каждое последующее клонирование репозитория включало в себя вышеупомянутые изменения. Изменения, описанные ниже, показывают, насколько просто построить и изменить блокчейн на ARK.

Включая пользовательскую транзакцию

Файлы, относящиеся к созданной нами пользовательской транзакции, были помещены в папку / plugins /.
Пользовательская транзакция была добавлена ​​в качестве плагина к мостовой цепочке путем вставки “message-transaction”: {} в конце файла plugins.js.
https://github.com/ArkEcosystem/poc-ark-messenger-core/blob/master/packages/core/bin/config/testnet/plugins.js

Отключение кеширования API

По умолчанию API кэширует результаты, которые возвращаются пользователю. Хотя обычно это очень хорошая функция, для приложения чата, где важна отзывчивость, но это не тот результат, что мы хотим. Поэтому кеширование API было отключено в файле plugins.js:
https://github.com/ArkEcosystem/poc-ark-messenger-core/blob/master/packages/core/bin/config/testnet/plugins.js

Code:
“@arkecosystem/core-api”: {cache: { enabled: false },…},

Отключение подсчета оценок

По умолчанию API возвращает оценки общего количества. Для ARK Messenger мы предпочитаем использовать точные цифры и поэтому принудительно устанавливаем этот параметр в переменной среде, которая используется в конфигурации:
https://github.com/ArkEcosystem/poc-ark-messenger-core/blob/master/packages/core/bin/config/testnet/.env

Code:
CORE_API_NO_ESTIMATED_TOTAL_COUNT=true

Установка минимального охвата сети

Поскольку ARK Messenger запускается как PoC, он запускается в Testnet. В этой сети другие ноды не подключены к сети. Чтобы процесс эмуляции не останавливался из-за несоблюдения условия минимального охвата сети, мы настроили его на 0 в файле plugins.js:

Code:
“@arkecosystem/core-p2p”: {server: {…minimumNetworkReach: 0,},
copper member
Activity: 493
Merit: 170
BountyMarketCap
ARK Desktop Wallet v2.9.1 - Расширенное использование плагинов

Выпущена новая версия Desktop Wallet. Это обновление направлено на добавление дополнительных функций в диспетчер плагинов и устранение недавно обнаруженных проблем.

Quote
Вы можете загрузить ARK Desktop Wallet по адресу https://ark.io/wallet или использовать новую функцию загрузки из своего текущего кошелька (доступна в v2.7.0 +).
С более частыми обновлениями Desktop Wallet мы хотим приносить постоянный поток улучшений для наших пользователей. В этом обновлении мы расширили удобство использования менеджера плагинов, предоставив разработчикам больше внутренних возможностей, добавив новый раздел языковых плагинов и многое другое, так что давайте перейдем к нему!


Что нового?

•   Добавлена иконка ARK Grants и обновлена конфигурация подключаемых модулей — с помощью разработки компании ARK новейшей программы ARK Grants (перейдите по ссылке, если вы хотите узнать больше о том, как вы можете получить финансирование, разрабатывая плагины Desktop Wallet), мы добавили специальный значок, который будет присваиваться каждому финансируемому плагину внутри рабочего стола кошелька. Мы также переместили иконку плагина ARK Official, чтобы она соответствовала этому дизайну и находилась рядом с названием плагина.



•   Разрешение плагинам добавлять языки — добавляет разрешение LANGUAGES (языки) которое позволяет плагинам добавлять новые языки. Все потенциальные языки теперь будут доступны через плагины.



•   Разбивка слов, если сообщение поля вендора велико — при просмотре модальной транзакции с большим полем вендора сообщение разбивается на отдельные строки, чтобы сохранить модальный размер разумным.



•   Возможность установить тип оплаты по умолчанию — добавляет новую опцию на страницу редактирования профиля, которая позволяет пользователю указать используемый тип оплаты транзакции по умолчанию, LAST (последний) или AVERAGE (средний).



•   Добавлена полоса прокрутки в список установленных плагинов — если установлено 5 или более плагинов, кошелек добавит полосу прокрутки в список плагинов.



•   Возможность использования стрелок влево и вправо на клавиатуре для переключения между изображениями плагинов — когда вы просматриваете определенные изображения плагинов с помощью ползунка, вы можете использовать стрелки влево или вправо для перемещения между ними.



•   Возможность добавления имен в темы плагинов — темы плагинов могут иметь дополнительное свойство name (имя) в своих настройках, которое будет отображаться в соответствующих раскрывающихся списках в боковом меню приложения и на странице редактирования профиля.



•   Добавлено отображение модуля деталей множественных платежей — несколько улучшений вида множественных платежей, такие как: выравнивание умного соединения справа и пометки сверху, добавление счета получателей, добавление общей сумму, добавление поля вендора и комиссии.
•   Список соединительной цепочки не обновляется автоматически после регистрации — После регистрации цепочки список цепочки теперь автоматически обновляется без необходимости перезагрузки или смены однорангового узла для его отображения.
•   Улучшения в мультиподписях — исправлена ошибка при выполнении отказа цепочки, исправлена проблема, при которой кнопка «подписать» все еще отображалась для транзакции с несколькими подписями, даже если было достигнуто количество минимальных подписей, а также исправлена потенциальная ошибка с проверкой вида голосования транзакции.
•   Возможность выбора известные кошельки из хранилища — известные кошельки теперь доступны в общем хранилище.
•   Предоставление большего количества компонентов пользовательского интерфейса для плагинов — теперь разработчики могут использовать компоненты пользовательского интерфейса, так как они новые теперь доступны для плагинов: WalletIdenticon, SvgIcon, ModalCloseConfirmation, ModalConfirmation и ModalWindow.
•   Предоставление диалогов сохранения / открытия для плагинов — методы electron_writeFile и electron_readFile теперь доступны для системы плагинов.
Доступ к ним можно получить, добавив разрешение DIALOGS: walletApi.dialogs.save(raw, filename, filters)и walletApi.dialogs.open(filters).
•   Замена API ценообразования на Platform SDK — мы заменили API ценообразования на недавно разработанный пакет Platform SDK, который будет использоваться для обмена данными между нашими приложениями.
•   Попробуйте сначала загрузить изображения локальных плагинов — вместо того, чтобы извлекать изображения для предварительного просмотра по определенным URL-адресам напрямую, попробуйте сначала получить изображения по пути по умолчанию (images/).
•   Добавлена область действия для маршрутов плагина и пунктов меню — область маршрутов плагина находится под идентификатором плагина. Навигация через разрешение ROUTES все еще может быть выполнена без использования области.
•   Возможность выставлять темы профилей для плагинов — для отображения графики в соответствующей цветовой схеме (темная / светлая) плагинам нужна информация о текущей определенной теме.
•   Разрешение одновременного поиска всех глобальных опций плагина — рефакторинг метода getOptions «песочниц» хранилища, чтобы можно было извлечь все глобальные опции.
•   Разрешение плагинам очистить все опции одновременно — расширяет изолированную программную среду хранения методом clear(global = false) , который позволяет плагинам очистить свои сохраненные данные сразу.
•   Скорректирована проверка формы транзакций для бизнеса и соединительной цепочки — мы добавили улучшенные проверки и исправили некоторые ошибки проверки при попытке зарегистрировать свой собственный бизнес или соединительную цепочку в APN.
•   Исправлена кнопка возврата после перезагрузки кошелька — кнопка возврата не работала должным образом, если вы перезагрузили кошелек.
•   Ошибка при воздействии с необработанной транзакцией при ее сохранении — исправлена ошибка, из-за которой повторная отправка просроченной транзакции завершалась неудачно, при этом все еще отображалось сообщение об успехе.
•   Обновление заголовков меню Mac — унифицированы заголовки меню на разных платформах.
•   Предоставление текущего однорангового модуля плагинам и разрешение параметров в запросах — текущий одноранговый узел может быть представлен через API-интерфейс кошелька к плагинам и может быть получен с помощью walletApi.peers.getCurrent(). Он также реорганизует методы get / post для принятия объекта параметров, который, например, позволяет передавать параметры запроса вместо создания URL-адреса.
•   Отображение однорангового обнаружения для плагинов — предоставление экземпляра однорангового обнаружения для системы плагинов. Экземпляр создается путем использования метода диспетчеризации getPeerDiscovery из модуля однорангового хранилища, чтобы не дублировать логику создания экземпляра.
•   Предоставление плагина BigNumber и сервиса Datetime для плагинов — мы добавили новое разрешение плагина UTILS, которое предоставляет плагин BigNumber и сервис datetime, к которым можно обращаться как walletApi.utils.bigNumber и walletApi.utils.datetime соответственно.
•   Добавлена функция «смотреть» для разрешенных ключей компонентов — позволяет использовать наблюдателей в компонентах плагинов.
•   Разрешено скрытие кнопки отмены в модуле подтверждения — при определенных обстоятельствах имеет смысл использовать модуль подтверждения только с одной опцией. Этот PR добавляет новое предложение к компоненту ModalConfirmation , которое позволяет скрыть кнопку отмены.
•   Добавлены группы типов при вводе последней комиссии — последние сохраненные комиссии сгруппированы по типу, что не позволяет магистральным транзакциям переопределять последние комиссии стандартных транзакций.
•   Ожидание следующего тика при фокусировке ввода пароля / парольной фразы — при переключении видимости парольной фразы и ввода пароля фокус устанавливается до полной визуализации компонента, таким образом вызывая фокусировку в начале ввода, а не в конце.



Изменения в цифрах

Начиная с предыдущего выпуска:

•   11 различных разработчиков вносят свой вклад в ARK Desktop Wallet.
•   70 новых фиксаций в ARK Desktop Wallet.
•   179 файлов изменено в ARK Desktop Wallet.
•   6,978 строчек кода добавлено в ARK Desktop Wallet.
•   1,804 строки кода удалены из ARK Desktop Wallet.



Хеши для v2.9.1 Desktop Wallet

•   Linux (ark-desktop-wallet-linux-x64–2.9.1.tar.gz)
708e52ee9eea5b21390bebd18d278a3c6f7579bd0d3d168f4c375a0984b24778
•   MacOS (ark-desktop-wallet-mac-2.9.1.dmg)
fe428a1d7e89fcaa870c70db9a19de93bd9def66460e03eef0f80500f7d72669
•   Ubuntu (ark-desktop-wallet-linux-amd64–2.9.1.deb)
06537ff90663560d82b710bb28d3826755924caf75b8d5ce5ddca271505ea7f1
•   Windows X86 & X64 (ark-desktop-wallet-win-2.9.1.exe)
b73c6ef213f7ecf250e8ccb52f9e1171d51f090469b1b8aa1f0aeae1d1c94239
•   Linux-AppImage (ark-desktop-wallet-linux-x86_64–2.9.1.AppImage)
c5d6f083630fcb9f1910714dac567678359c7c6563baa01b146e8244f0623950



Я нашел ошибку / проблему - что мне делать?

Пожалуйста, создайте тему и опишите все подробности или найдите уже созданную тему на странице ARK Desktop Wallet.


Я хочу помочь с развитием - что мне делать?

Пожалуйста, откройте пулл-запрос, и не забудьте, что мы также запускаем Github баунти кампанию для разработчиков, так что вы можете заработать дополнительный ARK.


Оригинал статьи: https://blog.ark.io/ark-desktop-wallet-v2-9-1-expanded-plugin-usability-548d94e51dc3
legendary
Activity: 2310
Merit: 1899
Leading Crypto Sports Betting & Casino Platform
Релиз ARK Mobile Wallet v1.8.0 - расширенная поддержка разработчиков



Последнее обновление ARK Mobile Wallet уже здесь! Эта версия ориентирована на улучшение взаимодействия с пользователем с помощью новых полей ввода и упрощает разработку благодаря обновленным зависимостям, большему охвату тестовых возможностей и новым функциям (режим разработчика, Angular Storybook и т. д.).

Мы перешли к более коротким циклам выпуска продуктов ARK, и ARK Mobile Wallet станет очередным обновлением. Этот релиз включает в себя несколько обновлений дизайна и улучшенное взаимодействие с пользователем.

Вы можете обновить ARK Mobile Wallet из Google Play/Apple's App Store или посетить https://android.ark.io (Android)/https://ios.ark.io (iOS).

Исходный код движется к тому, чтобы быть более ориентированным на разработчика (версии обновления Ionic и Angular), увеличивая охват тестами путем написания тестовых примеров и многого другого.

Давайте рассмотрим изменения в этом новом выпуске.

Что нового?

- Унифицированные поля ввода - мы унифицировали дизайн полей ввода, которые будут использоваться в нашей линейке продуктов.



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



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



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



С помощью Журнала Событий вы сможете увидеть детали процессов, происходящих за кулисами (включая ошибки для упрощения отладки).



- Настройки стиля экрана подтверждения пароля - исправлены стили на обоих экранах подтверждения пароля и 2-го пароля.



- Реализована Angular Storybook - Storybook (Книга историй - прим. KTChampions) похожа на веб-редактор, где вы можете конструировать компоненты и их взаимодействия изолированно и визуально видеть, как они работают.



- Исправлена кнопка «Назад» на экране панели кошелька - навигация по маршруту кошелька при нажатии.

- Крупное обновление версии Angular с 8 до 9 - мы обновили Angular до версии 9.x, добавив множество улучшений, ориентированных на разработчиков, исправление ошибок и повышение производительности.

- Миграция из TSLint в ESLint - из-за устаревания TSLint мы обновляемся, чтобы использовать вместо него ESLint.

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

Изменения в цифрах
Считая с предыдущего релиза:

- 4 разных разработчика, участвовали в работе над ARK Mobile Wallet.
- 48 новых изменений в ARK Mobile Wallet.
- 265 файлов изменено в ARK Mobile Wallet.
- 26 472 строки кода добавлено в ARK Mobile Wallet.
- 17,010 строк кода удалены из ARK Mobile Wallet.

Я нашел ошибку/проблему - что мне делать?

Пожалуйста, откройте обсуждение со всеми подробностями на странице Проблемы ARK Mobile Wallet.

Я хочу помочь с разработкой - что мне делать?

Пожалуйста, создайте запрос на добавление, и не забудьте, что мы также запускаем баунти для разработчиков на Github, так что вы можете заработать дополнительные токены ARK.

Оригинал: https://blog.ark.io/ark-mobile-wallet-v1-8-0-released-enhanced-developer-support-ed64f4257020
Автор: Rok Černec
Перевод: KTChampions

Буду благодарен за помощь в исправлении ошибок и неточностей.
member
Activity: 78
Merit: 14



Арк Мессенджер учебник - часть 2
Учебное пособие по разработке автономного и приватного приложения для обмена сообщениями



Приветствую всех во второй части нашей серии руководств, основанных на доказательстве концепции ARK Messenger (PoC). В первой части мы создали среду разработки и развернули собственную настраиваемую цепочку мостов. Эта серия была создана  с документацией, предоставленной делегатом Лемием как часть ARK Messenger Proof-of-Concept, финансируемой программой грантов ARK.


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



Начинаем


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

ARK Messenger реализует пользовательскую транзакцию сообщения. Это транзакция, которая будет содержать зашифрованное сообщение, отправляемое пользователем. Транзакция должна соответствовать следующим правилам:

  • Установите сумму перевода на 0 и примените низкую статическую комиссию (в настоящее время 0,01).
  • Уметь хранить относительно большой объем данных сообщения (1024 байта).
  • Должен иметь уникальный тип и группу типов (101, 1001).

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

Как понимать и описывать типы пользовательских транзакций.




Создание пользовательской транзакции

Создание пользовательской транзакции - простой процесс. В качестве шаблона мы будем использовать пользовательскую транзакцию ARK Messenger - Message Transaction.

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

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



Транзакция сообщения (создание нашей пользовательской транзакции)

В самом верху мы определяем наш пользовательский тип и группу типов:
Code:
const MESSAGE_TYPE = 101;const MESSAGE_TYPE_GROUP = 1001;

Чуть ниже мы определяем нашу схему транзакций:

Code:
public static getSchema(): Transactions.schemas.TransactionSchema {return schemas.extend(schemas.transactionBaseSchema, {…}}

Одно отличие, которое вы заметите, в отличие от транзакции регистрации бизнеса, мы включили поле receientId в нашу схему. Это связано с тем, что это поле используется в качестве «идентификатора канала» для наших целей. Кроме того, мы определяем остальную часть транзакции и наш объект сообщения, который будет использоваться для данных сообщения.

Ниже схемы мы определяем нашу статическую плату 0,01. Мы используем значение 1000000, поскольку ARK SDK не работает с числами с плавающей запятой, а количество десятичных разрядов равно 8.

Что касается функциональности serde (сериализатор / десериализатор); в основном она работает так же, как транзакция регистрации бизнеса, за исключением двух важных вещей:

Буферная функция writeUint8 ограничена размером 256 байт. Поскольку мы хотим обрабатывать данные сообщения максимум 1024 байта, мы должны вместо этого использовать вариант writeUint16.
Поскольку мы хотим использовать в транзакции receientId, мы должны включить его и в процесс serde:

Сериализатор:
Code:
const { addressBuffer, addressError } = Identities.Address.toBuffer(data.recipientId);
options.addressError = addressError;
buffer.append(addressBuffer);

Десериализатор:
Code:
data.recipientId = Identities.Address.fromBuffer(buf.readBytes(21).toBuffer());

Обработчик сообщений


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

Используя throwIfCannotBeApplied, мы явно проверяем правильность данных сообщения:

Code:
const { data }: Interfaces.ITransaction = transaction;const { message }: { message: string } = data.asset.messageData;if (!message) {throw new MessageTransactionAssetError();}await super.throwIfCannotBeApplied(transaction, wallet, databaseWalletManager);

В applyToSender и revertForSender мы выполняем действия по умолчанию применить и отменить. Методы applyToRecipient и revertForRecipient не используются, поскольку ни один из атрибутов получателя не изменяется в результате обработки Message Transaction.

Кроме того, мы позволяем базовому TransactionHandler… обрабатывать все остальное.



Построитель сообщений


Компоновщик, представленный в этом файле, будет использоваться в клиенте ARK Messenger для создания Message Transactions, когда пользователь отправляет сообщение.

Сначала мы инициализируем объект данных с помощью метода class constructor ():

Code:
constructor() {super();this.data.type = MessageTransaction.type;this.data.typeGroup = MessageTransaction.typeGroup;this.data.version = 2;this.data.fee = Utils.BigNumber.make("1000000");this.data.amount = Utils.BigNumber.ZERO;this.data.asset = { messageData: {} };this.data.recipientId = undefined;};

Далее мы создаем метод, который мы можем использовать для добавления данных сообщения в транзакцию:

Code:
public messageData(message: string): MessageTransactionBuilder {this.data.asset.messageData = {message,};};

Наконец, нам нужно добавить нестандартные поля в объект данных транзакции, когда он вызывается с помощью getStruct ():

Code:
const struct: Interfaces.ITransactionData = super.getStruct();struct.amount = this.data.amount;struct.asset = this.data.asset;struct.recipientId = this.data.recipientId;return struct;};


Тестирование построителя пользовательских транзакций

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

Вверху мы импортируем все необходимые пакеты:
Code:
import “jest-extended”;
import { Managers, Transactions } from “@arkecosystem/crypto”;
import { MessageTransactionBuilder } from “../src/builders”;
import { MessageTransaction } from “../src/transactions”;

Затем нам нужно внести некоторые коррективы с помощью менеджера конфигурации, чтобы иметь возможность фактически создать транзакцию. Сначала мы выбираем предустановку сети testnet и устанавливаем height равной 2. Это активирует этап AIP11.

Code:
Managers.configManager.setFromPreset(“testnet”);
Managers.configManager.setHeight(2);

Теперь мы включаем нашу новую пользовательскую транзакцию в реестр транзакций:
Code:
Transactions.TransactionRegistry.registerTransactionType(MessageTransaction);

На этом настройка завершена. Осталось создать тест, который проверяет, что транзакция может быть построена и проверена:
Code:
describe(“Test builder”, () => {
      it(“should verify correctly”, () => {
      const builder = new MessageTransactionBuilder();
      const tx = builder
         .messageData(“SomeMessage”)
         .nonce(“3”)
         .recipientId(“AYeceuGa7tTsyG6jgq7X6qKdoXt9iJJKN6”)        .sign(“clay harbor enemy utility margin pretty hub comic piece  aerobic umbrella acquire”);
      expect(tx.build().verified).toBeTrue();
      expect(tx.verify()).toBeTrue();
      });
});

Наконец, мы проверим эти транзакции в сети.


Тестирование пользовательской транзакции в сети

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

Информацию о том, как создать плагин, можно найти здесь: Как написать основной плагин.

Вы можете посмотреть наш файл плагина Message Transaction здесь: plugin.js.

Чтобы интегрировать плагин Message Transaction в bridgechain, мы просто должны включить его в конец файла plugins.js, который находится в ./packages/core/bin/config/ enjnetwork broadcast/plugins.js

Code:
module.exports = {….“message-transaction”: {},};

Теперь, когда мы запустим yarn setup для установки bridgechain, она также автоматически установит пользовательскую транзакцию и включит ее в качестве плагина при запуске.

Когда bridgechain работает (локально), мы можем проверить правильность интеграции пользовательской транзакции, проверив следующую конечную точку API: http://127.0.0.1:11003/api/transactions/types

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

Проверка завершается, когда транзакция транслируется и обрабатывается сетью. Теперь мы успешно реализовали нашу Message Transaction! Следующим шагом является разработка клиента чата, с которым пользователь будет взаимодействовать.


Использование пользовательской транзакции в клиенте

Как упоминалось ранее, клиент был создан с помощью ReactJS и написан на TypeScript. С полной кодовой базой можно ознакомиться здесь.

Чтобы использовать пользовательскую транзакцию в нашем клиенте чата, мы сначала должны включить некоторые файлы в наш проект. Части, которые нам нужны - это Transaction Message и Message Transaction Builder. Мы можем просто скопировать и вставить их ранее и поместить в папку / src /. Поскольку Message Transaction Handler используется только для ядра, его можно опустить.

Теперь мы можем просто импортировать Message Transaction Builder в любое место нашего приложения, чтобы использовать его. В клиенте ARK Messenger он импортируется в отдельный файл утилит, как вы можете видеть здесь.

Code:
import { encryptMessage, fetchRemoteNonce, broadcastTransaction } from ‘./index’;import { Transactions } from ‘@arkecosystem/crypto’;import { ITransactionData, IPostTransactionResponse } from ‘../interfaces’;import { MessageTransaction } from ‘../custom-transactions/message-transaction/transactions’;import { MessageTransactionBuilder } from ‘../custom-transactions/message-transaction/builders’;

Необходимо зарегистрировать новый тип транзакции в Реестре транзакций:

Code:
Transactions.TransactionRegistry.registerTransactionType(MessageTransaction);

Мы используем пользовательскую версию сети, определенную в переменной среды. Мы храним это в переменной const, которая будет передана построителю транзакций:

Code:
const NETWORK = Number(process.env.REACT_APP_NETWORK);

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

Code:
const createMessageTransaction = async (recipientId: string,encryptedMessage: string,passphrase: string,senderId: string): Promise => {const nonce = await fetchRemoteNonce(senderId);const tx = new MessageTransactionBuilder().network(NETWORK).recipientId(recipientId).messageData(encryptedMessage).nonce(nonce).sign(passphrase);return tx.getStruct();};export const sendMessage = async (recipientId: string,text: string,channelPassphrase: string,userPassphrase: string,userAddress: string): Promise => {const encryptedMessage = encryptMessage(text, channelPassphrase);try {const tx = await createMessageTransaction(recipientId,encryptedMessage,userPassphrase,userAddress);return broadcastTransaction(tx);} catch (err) {console.error(err);}};

Альтернативы этому подходу:

  • Загрузите пользовательскую транзакцию в качестве модуля в NPM.
  • Используйте подмодули Git.



Следующие шаги

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

Если вы застряли в какой-то момент, обязательно ознакомьтесь с нашими документами в центре обучения ARK. Кроме того, наша команда и разработчики сообщества активны в Slack, поэтому не стесняйтесь обращаться к нам!

Прочитайте наш новый технический документ, следите за нами в социальных сетях (Twitter | Facebook | Reddit), присоединяйтесь к нашему сообществу (Slack | Discord) и следите за обновлениями в нашем блоге на Medium и Steemit.


Перевод. Оригинал:ARK Messenger Tutorial — Part Two
staff
Activity: 3430
Merit: 3971
Crypto Swap Exchange
Вышел кошелёк ARK Desktop версии 2.9.1
Обновление включает в себя расширение функциональности плагинов, исправление множества ошибок и многое другое!

Загрузить можно с https://ark.io/wallet

Хэш-суммы для файлов кошелька 2.9.1 (SHA256)

Linux (ark-desktop-wallet-linux-x64–2.9.1.tar.gz)
708e52ee9eea5b21390bebd18d278a3c6f7579bd0d3d168f4c375a0984b24778

MacOS (ark-desktop-wallet-mac-2.9.1.dmg)
fe428a1d7e89fcaa870c70db9a19de93bd9def66460e03eef0f80500f7d72669

Ubuntu (ark-desktop-wallet-linux-amd64–2.9.1.deb)
06537ff90663560d82b710bb28d3826755924caf75b8d5ce5ddca271505ea7f1

Windows X86 & X64 (ark-desktop-wallet-win-2.9.1.exe)
b73c6ef213f7ecf250e8ccb52f9e1171d51f090469b1b8aa1f0aeae1d1c94239

Linux-AppImage (ark-desktop-wallet-linux-x86_64–2.9.1.AppImage)
c5d6f083630fcb9f1910714dac567678359c7c6563baa01b146e8244f0623950

Источник: https://bitcointalksearch.org/topic/m.54099868
legendary
Activity: 1708
Merit: 1615
#SWGT CERTIK Audited
продолжение:

Довольно много кода, поэтому давайте разобъем его на удобно читаемые части.

1. Абстрактный метод register вызывается загрузочными классами, которые отвечают за регистрацию сервисов. Этот метод должен регистрировать только то, что указано в его имени, и не запускать что-либо вроде HTTP-серверов

2. Метод загрузки вызывается классами загрузчика, которые отвечают за загрузку сервисов. Это должно действовать в зависимости от того, что произошло в методе register, то есть запустить HTTP-сервер.

3. Метод dispose вызывается классами начальной загрузки, отвечающими за удаление служб. Это должно действовать в зависимости от того, что произошло в методе загрузки, то есть остановить HTTP-сервер.

4. Метод manifest предоставляет доступ к package.json пакета для сбора информации, такой как имя или версия.

5. SetManifest вызывается классами начальной загрузки, которые отвечают за регистрацию сервисов. Файл package.json пакета будет автоматически загружен, проанализирован и, наконец, сохранен с помощью этого метода.

6. Метод name возвращает содержимое свойства name внутри файла package.json пакета.

7. Метод version возвращает содержимое свойства version в файле package.json пакета.
8.  Метод config предоставляет доступ к конфигурации пакета после его проверки и нормализации.
9. Метод setConfig вызывается загрузочными классами, которые отвечают за регистрацию сервисов. Конфигурация будет проверена, нормализована и, наконец, сохранена с помощью этого метода.

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

11.Метод configSchema вызывается классами начальной загрузки, которые отвечают за регистрацию служб. Этот метод должен возвращать схему @ hapi / joi, которая будет использоваться для проверки и нормализации конфигурации.

12.Метод dependencies вызывается классами начальной загрузки, которые отвечают за регистрацию сервисов. Возвращаемое значение этого метода должно быть массивом объектов, которые содержат информацию, такую ​​как имена и ограничения версии.

13.Методы enableWhen / disableWhen вызываются классами начальной загрузки при применении блока и отвечают за (де) регистрацию служб. Эти методы должны возвращать логическое значение, которое определяет, когда включать или отключать службу.

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

Это та функциональность, с которой поставщик услуг поставляется «из коробки», но в большинстве случаев единственными методами, с которыми вы будете взаимодействовать, являются регистрация, загрузка и удаление. Давайте посмотрим на пример поставщика сервисов, чтобы проиллюстрировать их использование.

Code:
import { Providers } from "@arkecosystem/core-kernel";
import { Server } from "@hapi/hapi";
export class ServiceProvider extends Providers.ServiceProvider {
    public async register(): Promise {
        this.app.bind("api").toConstantValue(new Server());
    }
public async boot(): Promise {
        await this.app.get("api").start();
    }
public async dispose(): Promise {
        await this.app.get("api").stop();
    }
}

1. Метод register связывает новый экземпляр сервера hapi.js с контейнером без его запуска.

2.Метод boot извлекает ранее зарегистрированный сервер из контейнера и вызывает метод start на нем.

3.Метод dispose извлекает ранее зарегистрированный сервер из контейнера и вызывает для него метод stop.

Как видите, зарегистрировать свои собственные сервисы довольно легко и без особых хлопот, и все четко обозначено, давайте закончим перечислением некоторых преимуществ этой новой архитектуры по сравнению с Core 2.0.

Преимущества нового жизненного цикла поставщика сервисов

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

Самым большим преимуществом для разработчиков пакетов является то, что теперь возможно изменять или расширять другие пакеты благодаря тому, как  работает самозагрузка приложения. Примером этого может быть плагин, который добавляет новые маршруты или плагины в пакет core-api перед запуском сервера. Все, что нужно - это разрешить сервер hapi.js из контейнера в методе register и вызвать обычные методы.

Это избавляет от необходимости раскручивать свой собственный HTTP-сервер, если вам просто нужно 1-2 дополнительных конечных точки API. Возможность изменять другие плагины до их запуска предоставит разработчикам больший контроль и возможности изменять поведение ядра.

Что дальше?
На этом завершается третья часть серии ARK Core Adventures. В следующей части мы рассмотрим, как ARK Core 3.0 является более расширяемым, чем когда-либо, и как вы можете воспользоваться этим, чтобы сократить время, затрачиваемое на разработку пакетов.

Предыдущие статьи:

Часть 1: Инфраструктура
https://blog.ark.io/lets-explore-ark-core-v3-part-1-infrastructure-5c8ba13c9c42

Часть 2: Bootstrap & Events
https://blog.ark.io/lets-explore-core-v3-part-2-bootstrap-events-f24adf70dfff
Pages:
Jump to: