Перейти к основному содержимому

Запросы к узлу

Узел использует обычный JSON-RPC 2.0 поверх HTTP POST. Без рукопожатия, без шифрования; учётные данные для административной поверхности создаются автоматически.

Каждый вызов определяют два параметра:

  • Какой интерфейс. /v2/owner — администрирование узла. /v2/foreign — все операции чтения цепочки плюс отправка транзакций. Разделение описано в Node API.
  • Двойной конверт. Ответ содержит JSON-RPC result, а внутри него — Ok или Err. См. конверт ответа.

Учётные данные владельца находятся в ~/.epic/main/.api_secret (floo или user для других сетей), имя пользователя — литеральная строка epic. Вызовы Foreign API не требуют учётных данных. См. аутентификация.

Оба клиента принимают NODE_URL и EPIC_NETWORK, поэтому локальная цепочка из запустить локальную сеть не требует правок. Запускайте их из каталога examples:

NODE_URL=http://127.0.0.1:23413 EPIC_NETWORK=user python python/epic_node.py

Полный клиент

Требуется curl и jq.

examples/shell/node-status.sh
#!/usr/bin/env bash
# Chain status and tip from a local Epic node, over JSON-RPC.
# Needs curl and jq. See https://devdocs.epiccash.com/examples/node-api
set -euo pipefail

NODE_URL="${NODE_URL:-http://127.0.0.1:3413}"
EPIC_NETWORK="${EPIC_NETWORK:-main}"
SECRET_FILE="${SECRET_FILE:-$HOME/.epic/$EPIC_NETWORK/.api_secret}"

command -v jq >/dev/null || { echo "this script needs jq" >&2; exit 1; }

# jq exits non-zero on the Err branch, so a pipeline fails loudly instead of
# printing an error object as if it were data.
epic_ok() {
jq -e 'if .error then error("jsonrpc: \(.error)")
elif .result.Err then error("epic: \(.result.Err)")
else (.result.Ok // .result) end'
}

# Owner surface: needs the secret when the node has one. Status, peers, chain admin.
owner_rpc() {
local -a cred=()
[ -r "$SECRET_FILE" ] && cred=(-u "epic:$(cat "$SECRET_FILE")")
curl -s "${cred[@]}" \
-H 'Content-Type: application/json' \
-d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"$1\",\"params\":${2:-[]}}" \
"$NODE_URL/v2/owner" | epic_ok
}

# Foreign surface: no credential. Every chain read lives here.
foreign_rpc() {
curl -s \
-H 'Content-Type: application/json' \
-d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"$1\",\"params\":${2:-[]}}" \
"$NODE_URL/v2/foreign" | epic_ok
}

status=$(owner_rpc get_status)
echo "height: $(jq -r '.tip.height' <<<"$status")"
echo "sync state: $(jq -r '.sync_status' <<<"$status")"
echo "peers: $(jq -r '.connections' <<<"$status")"

echo "mempool: $(foreign_rpc get_pool_size)"
echo "stempool: $(foreign_rpc get_stempool_size)"
echo "version: $(foreign_rpc get_version | jq -r '.node_version')"

Статус цепочки

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

curl -s -u "epic:$(cat ~/.epic/main/.api_secret)" \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"get_status","params":[],"id":1}' \
http://127.0.0.1:3413/v2/owner | jq '.result.Ok'

В Windows PowerShell:

$secret = (Get-Content "$HOME\.epic\main\.api_secret" -Raw).Trim()
$auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("epic:$secret"))
$body = '{"jsonrpc":"2.0","method":"get_status","params":[],"id":1}'
Invoke-RestMethod -Uri 'http://127.0.0.1:3413/v2/owner' -Method Post -Body $body `
-ContentType 'application/json' -Headers @{ Authorization = "Basic $auth" }
total_difficulty is an object, not a number

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

{"total_difficulty": {"cuckaroo": 0, "cuckatoo": 1234, "randomx": 5678, "progpow": 9012}}

Получить блок

get_block находится на foreign-поверхности и принимает позиционные параметры, [height, hash, commit]. Передайте один и оставьте остальные null.

curl -s -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"get_block","params":[1000000,null,null],"id":1}' \
http://127.0.0.1:3413/v2/foreign | jq '.result.Ok.header | {height, timestamp, proof}'

Ядра (kernels) представлены в двух формах в зависимости от метода. get_block возвращает плоскую форму, тогда как get_kernel и get_last_n_kernels возвращают исходный тип с полем features с внешней тегировкой.

Отслеживать новые блоки

Node API не имеет механизма подписки, поэтому используется опрос. При целевом времени блока 60 секунд достаточно опрашивать каждые 10–15 секунд. Опрашивайте get_tip на foreign-поверхности — учётные данные не требуются.

examples/shell/watch-blocks.sh
#!/usr/bin/env bash
# Poll the tip and print each new block height. Needs curl and jq.
# The node also has a webhook mechanism if you would rather be pushed to;
# see [server.webhook_config] in epic-server.toml.
set -euo pipefail

NODE_URL="${NODE_URL:-http://127.0.0.1:3413}"
INTERVAL="${INTERVAL:-10}"

command -v jq >/dev/null || { echo "this script needs jq" >&2; exit 1; }

height() {
# tr -d '\r' because a Windows jq writes CRLF, which command substitution strips only the
# newline from. Without it the integer comparison below fails with "integer expression
# expected" and the loop never advances. Harmless on Linux and macOS.
curl -s -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"get_tip","params":[]}' \
"$NODE_URL/v2/foreign" | jq -e -r '.result.Ok.height' | tr -d '\r'
}

last=$(height)
echo "starting at height $last"

while true; do
sleep "$INTERVAL"
now=$(height)
while [ "$last" -lt "$now" ]; do
last=$((last + 1))
echo "new block: $last"
done
done

Для получения событий по модели push вместо опроса см. [server.webhook_config] в epic-server.toml — этот параметр позволяет отправлять POST-запросы при событиях транзакции, заголовка и блока.

Мемпул и пиры

Размер мемпула и версия — вызовы foreign-поверхности. Списки пиров — вызовы административной поверхности.

rpc() { curl -s -H 'Content-Type: application/json' -d "$1" http://127.0.0.1:3413/v2/foreign; }

rpc '{"jsonrpc":"2.0","method":"get_pool_size","params":[],"id":1}' | jq '.result.Ok'
rpc '{"jsonrpc":"2.0","method":"get_stempool_size","params":[],"id":1}' | jq '.result.Ok'

curl -s -u "epic:$(cat ~/.epic/main/.api_secret)" -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"get_connected_peers","params":[],"id":1}' \
http://127.0.0.1:3413/v2/owner | jq '.result.Ok | length'

Все остальные методы

Полный список методов JSON-RPC по интерфейсам

/v2/owner, определено в api/src/owner_rpc.rs:29:

get_status validate_chain compact_chain
get_peers get_connected_peers ban_peer
unban_peer get_onion_addresses

/v2/foreign, определено в api/src/foreign_rpc.rs:37:

get_header get_block get_blocks
get_tip get_version get_kernel
get_last_n_kernels get_outputs get_unspent_outputs
get_pmmr_indices get_pool_size get_stempool_size
get_unconfirmed_transactions push_transaction
get_block_template finalize_block_template submit_block

Типы ответов определены в api/src/types.rs.

Далее