Плагины и их API

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

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

  • Открыть основной заголовочный файл плагина (пример для database_api), изучить DEFINE_API_ARGS (название API метода, тип возвращаемого значения);

  • Открыть основной файл плагина (пример для database_api), изучить DEFINE_API (проверка параметров запроса, CHECK_ARGS_COUNT, формирование возвращаемого значения определенного типа);

  • Изучить plugin_initialize, который может обрабатывать boost::program_options::variables_map для более тонкой настройки плагина через конфигурационный файл ноды.

Протокол запросов

Все запросы должны быть сформированы в JSON и выполнены через RPC. Транспортный протокол зависит от настройки ноды, возможны варианты как JSON-RPC через стандартные HTTP запросы, так и через WebSocket.

Для этого в конфигурационном файле ноды должны быть подключены плагины: json_rpc, webserver. Чтобы принимать транзакции от пользователей также должен быть включен плагин network_broadcast_api. Настройки для портов:

# Количество потоков для клиентов rpc. Оптимальное значение *количество ядер минус 1*
webserver-thread-pool-size = 2

# IP:PORT для HTTP подключений
webserver-http-endpoint = 0.0.0.0:8090

# IP:PORT для WebSocket подключений
webserver-ws-endpoint = 0.0.0.0:8091

Чтобы обрабатывать запросы с поддержкой SSL, необходимо пробросить используемые порты через проксирующий сервер (например, nginx или apache), тогда станут возможными запросы через https/wss.

Формирование API запроса

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

{"id":REQUEST_ID,"jsonrpc":"2.0","method":"call","params":["PLUGIN_NAME","PLUGIN_API_METHOD",[ARGS]]}
  • REQUEST_ID — номер запроса, носит необязательный характер (можно все запросы нумеровать единицей), но при соединении через web sockets (ws) позволяет ассоциировать ответы по запросам с аналогичным id;

  • PLUGIN_NAME — название плагина, к которому выполняется запрос (например: database_api, committee_api);

  • PLUGIN_API_METHOD — название метода, обрабатывающего запрос (например: get_accounts из database_api);

  • ARGS — массив упорядоченных параметров, передаваемый методу плагина.

network_broadcast_api

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

  • broadcast_block — передача подписанного блока (signed_block) другим узлам сети;

  • broadcast_transaction — передача подписанной транзакции (signed_transaction) другим узлам сети;

  • broadcast_transaction_synchronous — передача подписанной транзакции (signed_transaction) другим узлам сети (ждет вхождения в блок и возвращает хэш транзакции, номер блока и номер транзакции в блоке, или возвращает false в случае истечения срока действия транзакции);

  • broadcast_transaction_with_callback — то же, что и broadcast_transaction_synchronous, кроме проверки транзакции на валидность перед передачей в пул транзакций и регистрации метода обратного вызова (callback).

database_api

  • get_account_count — возвращает количество аккаунтов в сети;

  • get_accounts — возвращает массив аккаунтов по запрошенным логинам (отличается от lookup_account_names дополнительной информацией);

Пример:

{"id":1,"method":"call","jsonrpc":"2.0","params":["database_api","get_accounts",[["xel"]]]}

Ответ:

[
  {
    "id": 89772,
    "name": "xel",
    "owner": {
      "weight_threshold": 1,
      "account_auths": [],
      "key_auths": [
        [
          "GLS53nbKGcMwXw8zWMNLBm5XXLTW9fqZeQT5J7dC3Qso7GwJ7F8Hb",
          1
        ]
      ]
    },
    "active": {
      "weight_threshold": 1,
      "account_auths": [],
      "key_auths": [
        [
          "GLS81ApmkpdaJfbCXe7ZkbaiMeVcaQFW361sqC9r414fxVq9jNH3i",
          1
        ]
      ]
    },
    "posting": {
      "weight_threshold": 1,
      "account_auths": [],
      "key_auths": [
        [
          "GLS7WLHYqZrf9RYW273X34Aee7mK9pet8t83xgQ8jxeeZXXG3cTvS",
          1
        ]
      ]
    },
    "memo_key": "GLS8iWbEMQB3WaXHLrCVyDoJAuPQhaiCby3g3PNL4h2hdWq7kiACb",
    "json_metadata": "{"profile":{}}",
    "proxy": "",
    "last_owner_update": "2019-05-10T14:10:30",
    "last_account_update": "2019-05-10T14:10:30",
    "created": "2017-12-06T01:22:18",
    "mined": false,
    "owner_challenged": false,
    "active_challenged": false,
    "last_owner_proved": "1970-01-01T00:00:00",
    "last_active_proved": "1970-01-01T00:00:00",
    "recovery_account": "lex",
    "last_account_recovery": "1970-01-01T00:00:00",
    "reset_account": "null",
    "comment_count": 4,
    "lifetime_vote_count": 0,
    "post_count": 0,
    "can_vote": true,
    "voting_power": 9802,
    "last_vote_time": "2020-01-05T12:10:48",
    "balance": "23.549 GOLOS",
    "savings_balance": "0.000 GOLOS",
    "sbd_balance": "0.000 GBG",
    "sbd_seconds": "32824410702",
    "sbd_seconds_last_update": "2020-02-17T12:02:54",
    "sbd_last_interest_payment": "2018-02-05T16:51:54",
    "savings_sbd_balance": "0.000 GBG",
    "savings_sbd_seconds": "0",
    "savings_sbd_seconds_last_update": "2019-12-11T16:05:15",
    "savings_sbd_last_interest_payment": "2019-12-11T16:05:15",
    "savings_withdraw_requests": 0,
    "vesting_shares": "341688.730149 GESTS",
    "delegated_vesting_shares": "0.000000 GESTS",
    "received_vesting_shares": "0.000000 GESTS",
    "vesting_withdraw_rate": "0.000000 GESTS",
    "next_vesting_withdrawal": "1969-12-31T23:59:59",
    "withdrawn": "185064241674",
    "to_withdraw": "185064241674",
    "withdraw_routes": 0,
    "benefaction_rewards": 0,
    "curation_rewards": 0,
    "delegation_rewards": 0,
    "posting_rewards": 0,
    "proxied_vsf_votes": [
      0,
      0,
      0,
      0
    ],
    "witnesses_voted_for": 0,
    "average_bandwidth": 2721294841,
    "average_market_bandwidth": 1080000000,
    "lifetime_bandwidth": "632909000000",
    "lifetime_market_bandwidth": "6119410000000",
    "last_bandwidth_update": "2020-02-18T10:58:18",
    "last_market_bandwidth_update": "2020-02-07T02:04:09",
    "last_comment": "2020-02-18T10:54:03",
    "last_post": "1970-01-01T00:00:00",
    "post_bandwidth": 0,
    "witness_votes": [],
    "reputation": 0,
    "posts_capacity": 3,
    "comments_capacity": 32112,
    "voting_capacity": 12,
    "referrer_account": "",
    "referrer_interest_rate": 0,
    "referral_end_date": "1970-01-01T00:00:00",
    "referral_break_fee": "0.000 GOLOS",
    "last_active_operation": "2020-02-17T12:02:54"
  }
]
  • get_block — возвращает информацию о блоке по его номеру;

Пример:

{"id":1,"method":"call","jsonrpc":"2.0","params":["database_api","get_block",["34940353"]]}

Ответ:

{
  "previous": "021525c0c311e480cde023eea5c2ba26e0d06c82",
  "timestamp": "2020-02-19T12:09:15",
  "witness": "pzm",
  "transaction_merkle_root": "0000000000000000000000000000000000000000",
  "extensions": [],
  "witness_signature": "1f17e84a65e103c9cc476d27a29dbba4e5100ab60c79015418a5eeab0cf867b1ee7b4407b408b6d2d28fed9f08820defadb7f4ba715f4c520bb49c3fa5e5e8412a",
  "transactions": []
}
  • get_chain_properties — возвращает медианные значения голосуемых параметров сети;

Пример:

{"id":1,"method":"call","jsonrpc":"2.0","params":["database_api","get_chain_properties",[]]}

Ответ:

{
  "account_creation_fee": "1.000 GOLOS",
  "maximum_block_size": 65536,
  "sbd_interest_rate": 0,
  "create_account_min_golos_fee": "0.030 GOLOS",
  "create_account_min_delegation": "0.150 GOLOS",
  "create_account_delegation_time": 2592000,
  "min_delegation": "0.010 GOLOS",
  "max_referral_interest_rate": 1000,
  "max_referral_term_sec": 15552000,
  "min_referral_break_fee": "0.001 GOLOS",
  "max_referral_break_fee": "100.000 GOLOS",
  "posts_window": 7200,
  "posts_per_window": 2,
  "comments_window": 32767,
  "comments_per_window": 50,
  "votes_window": 15,
  "votes_per_window": 5,
  "auction_window_size": 0,
  "max_delegated_vesting_interest_rate": 8000,
  "custom_ops_bandwidth_multiplier": 10,
  "min_curation_percent": 7500,
  "max_curation_percent": 7500,
  "curation_reward_curve": "square_root",
  "allow_distribute_auction_reward": true,
  "allow_return_auction_reward_to_fund": true,
  "worker_reward_percent": 1000,
  "witness_reward_percent": 1500,
  "vesting_reward_percent": 7500,
  "worker_request_creation_fee": "100.000 GBG",
  "worker_request_approve_min_percent": 1500,
  "sbd_debt_convert_rate": 100,
  "vote_regeneration_per_day": 10,
  "witness_skipping_reset_time": 21600,
  "witness_idleness_time": 2592000,
  "account_idleness_time": 15552000
}
  • get_dynamic_global_properties — возвращает данные о динамических глобальных свойствах сети;

Пример:

{"id":1,"method":"call","jsonrpc":"2.0","params":["database_api","get_dynamic_global_properties",[]]}

Ответ:

{
  "id": 0,
  "head_block_number": 34940424,
  "head_block_id": "021526082557e35d8f65271a46ddfec351eeb2de",
  "time": "2020-02-19T12:12:48",
  "current_witness": "blockchained",
  "total_pow": 1719078,
  "num_pow_witnesses": 172,
  "virtual_supply": "223046315.397 GOLOS",
  "current_supply": "200741691.274 GOLOS",
  "confidential_supply": "0.000 GOLOS",
  "current_sbd_supply": "7129967.558 GBG",
  "confidential_sbd_supply": "0.000 GBG",
  "total_vesting_fund_steem": "80100561.317 GOLOS",
  "total_vesting_shares": "251334390154.901765 GESTS",
  "total_reward_fund_steem": "254.756 GOLOS",
  "total_reward_shares2": "21159194891210756",
  "sbd_interest_rate": 0,
  "sbd_print_rate": 0,
  "sbd_debt_percent": 4046,
  "average_block_size": 318,
  "maximum_block_size": 65536,
  "current_aslot": 35108656,
  "recent_slots_filled": "340282366920938463463374607431768211455",
  "participation_count": 128,
  "last_irreversible_block_num": 34940409,
  "max_virtual_bandwidth": "5986734968066277376",
  "current_reserve_ratio": 20000,
  "custom_ops_bandwidth_multiplier": 10,
  "is_forced_min_price": true,
  "transit_block_num": 29585430,
  "transit_witnesses": "76766b0000000000000000000000000078746172000000000000000000000000646d696c617368000000000000000000726f706f7800000000000000000000006c657800000000000000000000000000676f6c6f73636f72650000000000000076696b00000000000000000000000000737465657073686f740000000000000073746968692d696f0000000000000000676f6c6f73696f0000000000000000006c6164797a6172756c656d0000000000797564696e612d63617400000000000063726561746f720000000000000000006b756e6100000000000000000000000064656e69732d736b7269706e696b00007072696d7573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "worker_requests": [
    [
      "91600047785731",
      0
    ]
  ]
}
  • get_escrow — возвращает информацию о трехсторонней сделке по логину аккаунта и идентификатору сделки (id);

  • get_expiring_vesting_delegations — возвращает список возвращаемой делегированной доли (по времени истечения возврата);

  • get_hardfork_version — возвращает версию текущего хардфорка;

  • get_next_scheduled_hardfork — возвращает следующий запланированный хардфорк;

  • get_potential_signatures — возвращает потенциальные публичные ключи для подписи транзакции;

  • get_recovery_request — возвращает данные по запросу на восстановление доступа к аккаунту;

  • get_required_signatures — возвращает публичные ключи из предложенных, которые необходимы для подписи транзакции (нужно направить транзакцию без подписи и предоставить открытые ключи);

  • get_transaction_hex — возвращает hex значение сырой транзакции;

  • get_vesting_delegations — возвращает список делегированной доли аккаунта;

  • get_withdraw_routes — возвращает массив путей понижения доли для аккаунта;

  • lookup_account_names — возвращает массив аккаунтов по запрошенным логинам;

  • lookup_accounts — возвращает массив логинов аккаунтов по нижней границе с указанием количества возвращаемых элементов (не более 1000);

  • verify_account_authority — проверяет подпись транзакции отдельным аккаунтом с указанием публичного ключа;

  • verify_authority — принимает подписанную транзакцию и возвращает TRUE, если транзакция подписана всеми необходимыми ключами;

account_by_key

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

Пример запроса:

{"id":1,"method":"call","jsonrpc":"2.0","params":["account_by_key","get_key_references",[["GLS53nbKGcMwXw8zWMNLBm5XXLTW9fqZeQT5J7dC3Qso7GwJ7F8Hb"]]]}

Ответ:

[
  [
    "xel"
  ]
]

account_history

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

Пример запроса:

{"id":1,"method":"call","jsonrpc":"2.0","params":["account_history","get_account_history",["xel","-1","1"]]}

Ответ:

[
  [
    84,
    {
      "trx_id": "de0c1837f59023dd183e1f6f0d338f60432af2ab",
      "block": 34910086,
      "trx_in_block": 1,
      "op_in_trx": 1,
      "virtual_op": 0,
      "timestamp": "2020-02-18T10:54:03",
      "op": [
        "comment_options",
        {
          "author": "xel",
          "permlink": "re-lex-re-on0tole-re-lex-re-on0tole-re-lex-voznagrazhdeniya-za-shering-po-socsetyam-i-otkaz-ot-flagov-20200218t105406785z",
          "max_accepted_payout": "1000000.000 GBG",
          "percent_steem_dollars": 10000,
          "allow_votes": true,
          "allow_curation_rewards": true,
          "extensions": []
        }
      ]
    }
  ],
  [
    85,
    {
      "trx_id": "b35973bbf446a37d3d64492388231f7d5531f93b",
      "block": 34910171,
      "trx_in_block": 0,
      "op_in_trx": 0,
      "virtual_op": 0,
      "timestamp": "2020-02-18T10:58:18",
      "op": [
        "delete_comment",
        {
          "author": "xel",
          "permlink": "re-lex-re-on0tole-re-lex-re-on0tole-re-lex-voznagrazhdeniya-za-shering-po-socsetyam-i-otkaz-ot-flagov-20200218t105406785z"
        }
      ]
    }
  ]
]

operation_history

  • get_ops_in_block — возвращает массив операций по номеру блока (можно указать необходимость показывать только виртуальные операции);

Пример:

{"id":1,"method":"call","jsonrpc":"2.0","params":["operation_history","get_ops_in_block",["31913871","false"]]}

Ответ:

[
  {
    "trx_id": "0000000000000000000000000000000000000000",
    "block": 31913871,
    "trx_in_block": 65535,
    "op_in_trx": 0,
    "virtual_op": 1,
    "timestamp": "2019-11-05T23:23:18",
    "op": [
      "producer_reward",
      {
        "producer": "xanoxt",
        "vesting_shares": "488.592569 GESTS"
      }
    ]
  }
]
  • get_transaction — возвращает данные транзакции по её хэшу (id);

witness_api

  • get_active_witnesses — возвращает массив делегатов в текущем раунде (из 21 слота, при наличии такого количества делегатов);

Пример:

{"id":1,"method":"call","jsonrpc":"2.0","params":["witness_api","get_active_witnesses",[]]}

Ответ:

[
  "blockchained",
  "litrbooh",
  "lex",
  "prizm.space",
  "aleksw",
  "pzm",
  "anyx",
  "miner-113",
  "ladyzarulem",
  "rise",
  "xanoxt",
  "on0tole",
  "primus",
  "lulz",
  "actual",
  "vvk",
  "lindsay",
  "erikkartmen",
  "arcange",
  "jackvote",
  "solox"
]
  • get_witness_by_account — возвращает делегата в соответствием с его логином;

  • get_witness_count — возвращает количество аккаунтов, заявивших о желании быть делегатом;

  • get_witness_schedule — возвращает очередь делегатов дополненную расчитанными медианными значениями параметров сети и мажориторной версией хардфорка;

  • get_witnesses — возвращает массив делегатов в соответствием с их id (можно запросить нескольких в массиве);

  • get_witnesses_by_vote — возвращает массив делегатов, отсортированных по потенциалу полученных голосов (указывается левая граница списка и количество возвращаемых значений в массиве, но не более 100);

  • lookup_witness_accounts — возвращает массив логинов аккаунтов, которые заявляли себя как делегаты (указывается левая граница списка и количество возвращаемых значений в массиве, но не более 1000).

Last updated