5 способов, как разработка приложений Ergo изменилась навсегда благодаря Appkit

This page is machine-translated.
Alexander Slesarenko

3 декабря 2019 г.

Благодарим Роберта Корнацки и Дениса Задорожного.

Ergo Appkit — это библиотека для
полиглотной разработки приложений Ergo на основе
GraalVM. GraalVM имеет много отличных
вариантов использования
. Расширяя эту тему, в этой статье мы рассмотрим некоторые функции Appkit,
унаследованные от GraalVM, и проведем вас шаг за шагом через процесс их использования.

Пример сценария

Мы создадим простое консольное приложение (называемое
FreezeCoin)
на Java, которое использует библиотеку Appkit. Используя Appkit, мы сможем легко отправить новую транзакцию на узел Ergo программно. Транзакция переведет заданное количество Erg в новую коробку, защищенную
следующим контрактом Ergo, написанным на ErgoScript (см. это
введение и более сложные
примеры
, чтобы узнать больше о ErgoScript).

// Контракт заморозки
{ 
  // Параметры
  // freezeDeadline: Int - номер будущего блока, после которого коробка может быть потрачена
  // ownerPk: SigmaProp - открытый ключ владельца новой коробки
  sigmaProp(HEIGHT > freezeDeadline) && ownerPk
}

Вкратце, коробка (и, следовательно, средства внутри коробки) заблокированы под контрактом (или скриптом) на блокчейне Ergo. Чтобы коробка могла быть потрачена, контракт должен оцениваться как истинный. Таким образом, лицо, желающее потратить коробку, должно убедиться, что контракт оценивается как истинный на основе закодированной логики внутри него.

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

  1. Текущий номер блока блокчейна Ergo (также известный как HEIGHT) больше, чем указанная дата окончания

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

Первое условие запрещает кому-либо тратить коробку до тех пор, пока блокчейн Ergo не вырастет до заданной высоты. Поскольку новые блоки в блокчейне создаются примерно каждые 2 минуты в среднем, используя текущую высоту блокчейна, легко определить любой желаемый срок задержки, такой как 1 день, 1 неделя или 1 месяц. (т.е. (60 / 2) * 24 * 7 = 5040, что является количеством блоков в неделю).

Теперь мы углубимся в то, как мы можем взять этот контракт заморозки и интегрировать его с библиотекой Apkit, чтобы создать консольное приложение FreezeCoin, чтобы любой желающий мог заморозить свои монеты, если они этого захотят. (Хотя этот контракт/dApp на самом деле не полезен, он является эффективным простым примером для демонстрации того, как работает этот стек технологий, чтобы вы могли сами создавать полезные dApps в будущем.)

1. Разработка приложений Ergo на Java

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

Пожалуйста, следуйте инструкциям по настройке для GraalVM и
Appkit, если вы хотите воспроизвести примеры ниже.

Чтобы использовать Appkit в нашей реализации Java FreezeCoin, мы должны добавить
следующую зависимость в файл gradle

dependencies {
    implementation("org.ergoplatform", "ergo-appkit_2.12", "3.1.0", "compile")
    ...
}

Кроме того, во время выполнения Appkit/наше приложение должно подключиться к узлу Ergo через REST API. Часто,
узел будет работать локально и будет доступен по адресу http://localhost:9052/. Это стандартный сценарий для любого, кто настроил полный узел, следуя этим
инструкциям
и использует стандартную конфигурацию.

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

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

freeze_coin_config.json:

{
  "node": {
    "nodeApi": {
      "apiUrl": "http://localhost:9052/",
      "apiKey": "вставьте ваш секретный apiKey, сгенерированный во время настройки узла"
    },
    "wallet": {
      "mnemonic": "мнемонический ключ, используемый для инициализации или восстановления кошелька узла",
      "password": "пароль, который вы выбрали для защиты кошелька",
      "mnemonicPassword": "пароль, который вы выбрали для защиты мнемоники"
    },
    "networkType": "TESTNET"
  },
  "parameters": {
    "newBoxSpendingDelay": "30",
    "ownerAddress": "3WzR39tWQ5cxxWWX6ys7wNdJKLijPeyaKgx72uqg9FJRBCdZPovL"
  }
}

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

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

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

public static void main(String[] args) {
    long amountToSend = Long.parseLong(args[0]);  // положительное значение в NanoErg
    ErgoToolConfig conf = ErgoToolConfig.load("freeze_coin_config.json");
    // остальная часть кода обсуждается ниже 
    ...
}

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

  int newBoxSpendingDelay = Integer.parseInt(conf.getParameters().get("newBoxSpendingDelay"));
  Address ownerAddress = Address.create(conf.getParameters().get("ownerAddress"));

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

ErgoNodeConfig nodeConf = conf.getNode();
ErgoClient ergoClient = RestApiErgoClient.create(nodeConf);

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

String txJson = ergoClient.execute((BlockchainContext ctx) -> {
    // используйте ctx здесь, чтобы создать и подписать новую транзакцию
    // затем отправьте ее на узел 
});

Лямбда, переданная в execute, вызывается, когда текущий контекст блокчейна
загружается из узла Ergo. В этой лямбде мы
разместим нашу бизнес-логику.

Сначала мы начинаем с некоторых вспомогательных шагов.

// доступ к кошельку, встроенному в узел Ergo 
// (используя кошелек, указанный через мнемонику, которую мы указали в freeze_coin_config.json)
ErgoWallet wallet = ctx.getWallet();

// вычисляем общее количество NanoErgs, которое нам нужно отправить в новую коробку 
// включая оплату за транзакционные сборы
long totalToSpend = amountToSend + Parameters.MinFee;

// запрашиваем неиспользованные коробки, которые покрывают необходимую сумму NanoErgs из кошелька
Optional<List<InputBox>> boxes = wallet.getUnspentBoxes(totalToSpend);
if (!boxes.isPresent())
    throw new ErgoClientException(
        "Недостаточно монет в вашем указанном кошельке для оплаты " + totalToSpend, null);
    
// создаем "доказатель", который является специальным объектом, который будет использоваться для подписания транзакции
// доказатель должен быть настроен с секретами вашего кошелька, которые необходимы для генерации подписей (т.е. доказательств)
ErgoProver prover = ctx.newProverBuilder()
    .withMnemonic(
            nodeConf.getWallet().getMnemonic(),
            nodeConf.getWallet().getPassword())
    .build();

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

// единственный способ создать транзакцию — использовать строителя tx, полученного из контекста
// строитель использует контекст для доступа к необходимым данным блокчейна.
UnsignedTransactionBuilder txB = ctx.newTxBuilder();

// создаем новую коробку, используя нового строителя, полученного от строителя транзакций
// в этом случае мы компилируем новый ErgoContract из кода ErgoScript заморозки
OutBox newBox = txB.outBoxBuilder()
        .value(amountToPay)
        .contract(ctx.compileContract(
                ConstantsBuilder.create()
                        .item("freezeDeadline", ctx.getHeight() + newBoxSpendingDelay)
                        .item("ownerPk", ownerAddress.getPublicKey())
                        .build(),
                "{ sigmaProp(HEIGHT > freezeDeadline) && ownerPk }"))
        .build();

Обратите внимание, чтобы скомпилировать ErgoContract из исходного кода скрипта заморозки, метод compileContract
требует, чтобы мы предоставили значения для именованных констант, которые используются в скрипте.
Если такие константы не используются, то можно передать ConstantsBuilder.empty().

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

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

// предоставляем строителю транзакции, какие коробки мы собираемся потратить, какие выходы
// должны быть созданы, общие транзакционные сборы и адрес для отправки сдачи
UnsignedTransaction tx = txB.boxesToSpend(boxes.get())
        .outputs(newBox)
        .fee(Parameters.MinFee)
        .sendChangeTo(prover.getP2PKAddress())
        .build();

И, наконец, мы:

  1. Используем доказатель для подписания построенной транзакции
  2. Таким образом, получаем экземпляр SignedTransaction
  3. Используем контекст блокчейна, чтобы отправить подписанную транзакцию на
    узел Ergo.

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

SignedTransaction signed = prover.sign(tx);
String txId = ctx.sendTransaction(signed);
return signed.toJson(true);

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

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


Теперь, когда весь код установлен, мы можем запустить наше приложение FreezeCoin, следуя следующим шагам
(при условии, что вы находитесь в директории, где вы клонировали
ergo-appkit-examples).

$ pwd
the/directory/you/cloned/ergo-appkit-examples
$ ./gradlew clean shadowJar 

Это соберет файл build/libs/appkit-examples-3.1.0-all.jar, содержащий
наше Java-приложение FreezeCoin и все его зависимости в одном большом jar-файле.
Обратите внимание, что этот шаг необходимо повторять после любых изменений в исходном коде Java нашего приложения.

Создав наше приложение, мы теперь можем использовать наше приложение FreezeCoin:

$ java -cp build/libs/appkit-examples-3.1.0-all.jar \
      org.ergoplatform.appkit.examples.FreezeCoin  1000000000 

Вы получите что-то вроде этого вывода в консоли.

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

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

2. Приложения Ergo с низким потреблением ресурсов и быстрой загрузкой

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

Давайте запустим FreezeCoin, используя команду time, чтобы
узнать реальное (время, прошедшее с начала до конца) время, которое требуется всей программе для выполнения.
Мы используем флаг -l, чтобы также напечатать использование памяти.

$ /usr/bin/time -l java -cp build/libs/appkit-examples-3.1.0-all.jar \
   org.ergoplatform.appkit.examples.FreezeCoin 1000000000
...
       4.97 real         8.41 user         0.69 sys
 513703936  максимальный размер резидентного набора
         0  средний размер общей памяти
         0  средний размер неразделяемых данных
         0  средний размер неразделяемого стека
    125010  восстановление страниц
      1216  ошибки страниц
         0  обмены
         0  операции ввода блоков
         0  операции вывода блоков
        13  отправленные сообщения
        86  полученные сообщения
         1  полученные сигналы
      2384  добровольные переключения контекста
     17409  недобровольные переключения контекста

Как видно, это маленькое приложение потребовало почти 4 секунды для выполнения на 2 параллельных потоках. Большая часть этого времени может быть отнесена к запуску JVM и
работе фона JIT-компилятора. Это довольно низкая производительность, и мы знаем, что можем сделать гораздо лучше.

К счастью, GraalVM предоставляет нам идеальное решение.

Мы можем решить эту врожденную проблему с JVM, скомпилировав Java-код
заранее в нативное исполняемое изображение через GraalVM. Это исключает необходимость использовать Java-компилятор в режиме реального времени.

Опыт для нас (разработчика, использующего GraalVM) довольно похож на обычный компилятор, такой как gcc. Обратите внимание,
что нам может потребоваться сначала запустить ./gradlew clean shadowJar.

$ ./gradlew clean shadowJar
$ native-image --no-server \
 -cp build/libs/appkit-examples-3.1.0-all.jar\
 --report-unsupported-elements-at-runtime\
  --no-fallback -H:+TraceClassInitialization -H:+ReportExceptionStackTraces\
   -H:+AddAllCharsets -H:+AllowVMInspection -H:-RuntimeAssertions\
   --allow-incomplete-classpath \
    --enable-url-protocols=http,https org.ergoplatform.appkit.examples.FreezeCoin freezecoin
[freezecoin:3133]    classlist:  35,217.78 ms
[freezecoin:3133]        (cap):   6,063.07 ms
[freezecoin:3133]        setup:   8,268.99 ms
[freezecoin:3133]   (typeflow):  60,238.25 ms
[freezecoin:3133]    (objects):  33,009.06 ms
[freezecoin:3133]   (features):   4,796.86 ms
[freezecoin:3133]     analysis: 102,876.01 ms
[freezecoin:3133]     (clinit):  11,642.43 ms
[freezecoin:3133]     universe:  13,718.96 ms
[freezecoin:3133]      (parse):   5,053.18 ms
[freezecoin:3133]     (inline):  18,317.24 ms
[freezecoin:3133]    (compile):  44,806.82 ms
[freezecoin:3133]      compile:  72,288.24 ms
[freezecoin:3133]        image:   7,955.29 ms
[freezecoin:3133]        write:   2,872.25 ms
[freezecoin:3133]      [total]: 243,813.30 ms

Простая команда выше создает полное нативное исполняемое приложение под названием freezecoin.

Чтобы подчеркнуть, это исполняемое приложение не является простым загрузчиком для JVM. На самом деле, оно не связывается с JVM и не включает
JVM никаким образом. native-image компилирует код FreezeCoin, а также любые
Java-библиотеки, от которых он зависит, до простого машинного кода.

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

$ otool -L freezecoin    # ldd freezecoin на Linux
freezecoin:
	/usr/lib/libSystem.B.dylib (версия совместимости 1.0.0, текущая версия 1252.50.4)
	/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (версия совместимости 150.0.0, текущая версия 1455.12.0)
	/usr/lib/libz.1.dylib (версия совместимости 1.0.0, текущая версия 1.2.11)

Если мы измерим это новое исполняемое приложение freezecoin, мы увидим, что оно запускается примерно в 8 раз быстрее и использует
примерно в 6 раз меньше памяти. Это означает, что вы не чувствуете той ощутимой паузы, которую всегда получаете при запуске
краткосрочной программы с JVM.

$ DYLD_LIBRARY_PATH=$GRAAL_HOME/jre/lib /usr/bin/time -l ./freezecoin 1800000000
        0.43 real         0.15 user         0.03 sys
  81289216  максимальный размер резидентного набора
         0  средний размер общей памяти
         0  средний размер неразделяемых данных
         0  средний размер неразделяемого стека
     20079  восстановление страниц
         0  ошибки страниц
         0  обмены
         0  операции ввода блоков
         0  операции вывода блоков
        13  отправленные сообщения
        86  полученные сообщения
         0  полученные сигналы
        11  добровольные переключения контекста
       138  недобровольные переключения контекста

Это всего лишь одно из многих преимуществ GraalVM, которые мы можем использовать с Appkit.

3. Разработка приложений Ergo на JavaScript, Python, Ruby

GraalVM поддерживает так называемое полиглотное программирование, при котором различные компоненты
приложения могут быть разработаны с использованием наиболее подходящего языка и затем
бесшовно объединены во время выполнения. Таким образом, уникальная библиотека, написанная, скажем,
на Java, может быть использована в приложении node.js, написанном на JavaScript, например.

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

Перед запуском примеров ниже (на JavaScript, Python и Ruby) убедитесь, что у вас работает
Java-версия FreezeCoin локально, чтобы убедиться, что все настроено правильно.

JavaScript

GraalVM может запускать JavaScript и
Node.js

приложения из коробки. Он совместим с ECMAScript 2019
спецификацией
.
Кроме того, загрузчики js и node принимают специальные командные параметры --jvm и --polyglot,
которые позволяют JS-скриптам получать доступ к объектам и классам Java.

Учитывая это, реализация FreezeCoin на JS может быть легко написана с использованием интерфейса API Appkit.
Пожалуйста, смотрите полный исходный код реализации FreezeCoin JS
для деталей.
Следующая команда использует загрузчик node, чтобы выполнить скрипт FreezeCoin.js.

$ node --jvm --vm.cp=build/libs/appkit-examples-3.1.0-all.jar \
  js-examples/FreezeCoin.js  1000000000

Обратите внимание, что пути в команде относительны к корню
каталога проекта ergo-appkit-examples.

Python

GraalVM может запускать Python
скрипты
, хотя
реализация Python все еще экспериментальная (см. также
раздел совместимости
для деталей).

Пример Python
FreezeCoin

можно выполнить с помощью следующей команды

$ graalpython --jvm --polyglot --vm.cp=build/libs/appkit-examples-3.1.0-all.jar \
   python-examples/FreezeCoin.py 1900000000

Ruby

GraalVM может запускать Ruby
скрипты
с использованием
реализации TruffleRuby, которая, однако, все еще экспериментальная (см. также
раздел совместимости
для деталей).
TruffleRuby нацелен на полную совместимость со стандартной реализацией Ruby, MRI, версии 2.6.2.

Пример Ruby
FreezeCoin

можно выполнить с помощью следующей команды

$ truffleruby --polyglot --jvm --vm.cp=build/libs/appkit-examples-3.1.0-all.jar \
    ruby-examples/FreezeCoin.rb 1900000000

4. Нативные общие библиотеки Ergo

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

Для этого мы объявляем один или несколько статических методов как @CEntryPoint.

public class FreezeCoin {
    ...
     /**
     * Точка входа, вызываемая из C, которая оборачивает {@link FreezeCoin#sendTx}
     */
    @CEntryPoint(name = "sendTx")
    public static void sendTxEntryPoint(
            IsolateThread thread,
            SignedWord amountToSendW,
            CCharPointer configFileNameC,
            CCharPointer resBuffer, UnsignedWord bufferSize) throws FileNotFoundException {
        long amountToSend = amountToSendW.rawValue();
        // Преобразуем C-строки в целевые Java-строки.
        String configFileName = CTypeConversion.toJavaString(configFileNameC);
        String txJson = sendTx(amountToSend, configFileName);

        // помещаем результирующую строку в предоставленный буфер
        CTypeConversion.toCString(txJson, resBuffer, bufferSize);
    }  
    ...
}

Затем мы можем скомпилировать в общую библиотеку и автоматически сгенерированный заголовочный
файл. Обратите внимание на использование параметра --shared.

$ native-image --no-server \
 -cp build/libs/appkit-examples-3.1.0-all.jar\
 --report-unsupported-elements-at-runtime\
  --no-fallback -H:+TraceClassInitialization -H:+ReportExceptionStackTraces\
   -H:+AddAllCharsets -H:+AllowVMInspection -H:-RuntimeAssertions\
   --allow-incomplete-classpath \
    --enable-url-protocols=http,https 
    --shared -H:Name=libfreezecoin -H:Path=c-examples
    
$ otool -L c-examples/libfreezecoin.dylib 
c-examples/libfreezecoin.dylib:
	.../c-examples/libfreezecoin.dylib (версия совместимости 0.0.0, текущая версия 0.0.0)
	/usr/lib/libSystem.B.dylib (версия совместимости 1.0.0, текущая версия 1252.50.4)
	/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (версия совместимости 150.0.0, текущая версия 1455.12.0)
	/usr/lib/libz.1.dylib (версия совместимости 1.0.0, текущая версия 1.2.11)

Теперь у нас есть возможность написать C
программу

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

#include <stdlib.h>
#include <stdio.h>

#include <libfreezecoin.h>

int main(int argc, char **argv) {
  graal_isolate_t *isolate = NULL;
  graal_isolatethread_t *thread = NULL;
  
  if (graal_create_isolate(NULL, &isolate, &thread) != 0) {
    fprintf(stderr, "ошибка graal_create_isolate\n");
    return 1;
  }

  char * configFileName = "freeze_coin_config.json";

  // получаем amountToSend из аргументов cmd и вызываем создание транзакции
  long amountToSend = atol(argv[1]);
  char result[1024 * 16];
  sendTx(thread, amountToSend, configFileName, result, sizeof(result));

  // выводим сериализованный результат
  printf("%s\n", result);

  if (graal_detach_thread(thread) != 0) {
    fprintf(stderr, "ошибка graal_detach_thread\n");
    return 1;
  }
  return 0;
}

Мы можем скомпилировать это с помощью наших стандартных системных инструментов и легко запустить наш исполняемый файл (установите LD_LIBRARY_PATH=. на Linux).

$ clang -Ic-examples -Lc-examples -lfreezecoin c-examples/freezecoin.c -o call_freezecoin
$ otool -L call_freezecoin
$ DYLD_LIBRARY_PATH=$GRAAL_HOME/jre/lib ./call_freezecoin 1000000000

5. Отладка вашего полиглотного приложения Ergo

Вы можете отлаживать JS, Python и Ruby в IntelliJ, но если по какой-то причине это
не работает для вас или не подходит вашему предпочтительному редактору, GraalVM предлагает другой вариант.

Все языки GraalVM (кроме Java) реализованы с использованием общего
фреймворка Truffle.
Truffle позволяет реализовать инструменты, такие как отладчики, один раз и сделать их доступными
для всех поддерживаемых языков.

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

$ ruby --polyglot --jvm --inspect --vm.cp=build/libs/appkit-examples-3.1.0-all.jar \
    ruby-examples/FreezeCoin.rb 1900000000
Отладчик слушает на порту 9229.
Чтобы начать отладку, откройте следующую URL-адрес в Chrome:
    chrome-devtools://devtools/bundled/js_app.html?ws=127.0.0.1:9229/30c7da1e-7558a47d09b
...

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

Отладчик

Заключение

И с этим всем сказанным и сделанным, мы видим, насколько легко использовать Appkit для
разработки приложений Ergo. Appkit полагается на те же самые основные библиотеки, которые
использовались для реализации протокола консенсуса Ergo. Эти библиотеки включают
компилятор ErgoScript, криптографию, интерпретатор байт-кода, сериализаторы данных
и другие основные компоненты. Используя GraalVM, мы можем повторно использовать эти проверенные
и протестированные компоненты в различных контекстах приложений без каких-либо модификаций
или переписывания их самостоятельно.

Неважно, используете ли вы Java, JavaScript, Python или Ruby, вы можете воспользоваться
Appkit с GraalVM, чтобы значительно упростить процесс
взаимодействия с блокчейном Ergo, создавая нативные (d)Apps.

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

Ссылки

  1. Сайт Ergo
  2. Исходники Ergo
  3. Ergo Appkit
  4. Примеры Ergo Appkit
  5. GraalVM

Share post

Ergo Infrastructure DAO: Децентрализация основного каркаса экосистемы Ergo

Ergo Infrastructure DAO: Децентрализация основного каркаса экосистемы Ergo

Миссия Ergo всегда была основана на децентрализации, не только на уровне консенсуса, но и на всем стеке.

Ergo Platform

13 августа 2025 г.

Mew Finance: Игровой DeFi инструмент для экосистемы Ergo

Mew Finance: Игровой DeFi инструмент для экосистемы Ergo

Mew Finance — это децентрализованный набор приложений на блокчейне Ergo.

Ergo Platform

12 августа 2025 г.

Lithos: Децентрализация майнинга с помощью ончейн пулов

Lithos: Децентрализация майнинга с помощью ончейн пулов

Lithos — это новый протокол, разработанный для изменения работы майнинг-пулов, перемещая их в ончейн, предоставляя майнерам полный.

Ergo Platform

24 июля 2025 г.

Sigma 6.0: Более умный и гибкий Ergo

Sigma 6.0: Более умный и гибкий Ergo

Sigma 6.0 — это значительное предложенное обновление для блокчейна Ergo.

Ergo Platform

23 июля 2025 г.

Формирование будущего Rosen: Общественный призыв к пяти ключевым предложениям казначейства

Формирование будущего Rosen: Общественный призыв к пяти ключевым предложениям казначейства

Соучредитель Rosen, Armeanio, представил пять новых предложений в казначейство Rosen.

Ergo Platform

9 июля 2025 г.

Расширенный UTXO Ergo и восход искусственного экономического интеллекта

Расширенный UTXO Ergo и восход искусственного экономического интеллекта

Практическое видение автономных экономических агентов Автономные экономические агенты на блокчейне Ergo выполняют полезную работу.

Ergo Platform

12 мая 2025 г.

ErgoHACK X: Искусственный Интеллект на Блокчейне Ergo

ErgoHACK X: Искусственный Интеллект на Блокчейне Ergo

Празднование Десятилетия Децентрализованных Инноваций Присоединяйтесь к 10-летнему юбилею ErgoHACK и будьте на переднем крае револ.

Ergo Platform

10 апреля 2025 г.