コンテンツにスキップ

通貨供給量の照会⚓︎

初級

取引所や市場データアグリゲーターは、時価総額やトークン指標を表示するために正確な供給量の数値を必要とします。

Symbolネットワークは、専用のRESTエンドポイントを通じて、ネイティブ通貨であるXYMの最大供給量、総供給量、および循環供給量を公開しています。

このチュートリアルでは、それぞれの値を照会し、それらから追加の指標を導き出す方法を説明します。

前提条件⚓︎

このチュートリアルでは、SDKを必要とせずにSymbol REST APIを使用します。 HTTPリクエストを行う方法さえあれば実行可能です。

完全なコード⚓︎

このチュートリアルの完全なコード一覧を以下に示します。 詳細な手順ごとの説明は次のセクションで行います。

import os
import urllib.request
from decimal import Decimal

NODE_URL = os.getenv('NODE_URL', 'https://reference.symboltest.net:3001')
print(f'Using node {NODE_URL}')

SUPPLY_URL = f'{NODE_URL}/network/currency/supply'

try:
    with urllib.request.urlopen(f'{SUPPLY_URL}/max') as response:
        maximum_supply = Decimal(response.read().decode().strip())
    print(f'Maximum supply: {maximum_supply:,.6f} XYM')

    with urllib.request.urlopen(f'{SUPPLY_URL}/total') as response:
        total_supply = Decimal(response.read().decode().strip())
    print(f'Total supply: {total_supply:,.6f} XYM')

    with urllib.request.urlopen(f'{SUPPLY_URL}/circulating') as response:
        circulating_supply = Decimal(response.read().decode().strip())
    print(f'Circulating supply: {circulating_supply:,.6f} XYM')

    non_circulating_supply = total_supply - circulating_supply
    print(f'Non-circulating supply: {non_circulating_supply:,.6f} XYM')

    unminted_supply = maximum_supply - total_supply
    print(f'Unminted supply: {unminted_supply:,.6f} XYM')

except Exception as error:
    print(error)

Download source

const NODE_URL = process.env.NODE_URL ||
    'https://reference.symboltest.net:3001';
console.log(`Using node ${NODE_URL}`);

const SUPPLY_PATH = '/network/currency/supply';

// Convert the returned decimal string (whole XYM) to atomic units.
// A float conversion would lose precision when the value has more
// than 15 significant digits.
const toAtomic = s => {
    const [whole, frac = ''] = s.trim().split('.');
    return (BigInt(whole) * 1_000_000n) + BigInt(frac.padEnd(6, '0'));
};
// Format an atomic amount back as whole XYM with 6 decimals.
const fmt = v =>
    `${(v / 1_000_000n).toLocaleString('en-US')}.` +
    `${(v % 1_000_000n).toString().padStart(6, '0')}`;

try {

    const maximumResponse = await fetch(`${NODE_URL}${SUPPLY_PATH}/max`);
    const maximumSupply = toAtomic(await maximumResponse.text());
    console.log(`Maximum supply: ${fmt(maximumSupply)} XYM`);

    const totalResponse = await fetch(`${NODE_URL}${SUPPLY_PATH}/total`);
    const totalSupply = toAtomic(await totalResponse.text());
    console.log(`Total supply: ${fmt(totalSupply)} XYM`);

    const circulatingResponse =
        await fetch(`${NODE_URL}${SUPPLY_PATH}/circulating`);
    const circulatingSupply = toAtomic(await circulatingResponse.text());
    console.log(`Circulating supply: ${fmt(circulatingSupply)} XYM`);

    const nonCirculatingSupply = totalSupply - circulatingSupply;
    console.log(
        `Non-circulating supply: ${fmt(nonCirculatingSupply)} XYM`);

    const unmintedSupply = maximumSupply - totalSupply;
    console.log(`Unminted supply: ${fmt(unmintedSupply)} XYM`);
} catch (error) {
    console.log(error);
}

Download source

//JAVA 21+

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.util.Locale;

final class QueryCurrencySupply {
    private static final HttpClient HTTP_CLIENT =
        HttpClient.newHttpClient();

    private static final String NODE_URL = System.getenv().getOrDefault(
        "NODE_URL", "https://reference.symboltest.net:3001");

    private static BigDecimal fetchSupplyValue(
        final String supplyType
    ) throws IOException, InterruptedException {
        final String supplyPath =
            String.format("/network/currency/supply/%s", supplyType);
        final String url = String.format("%s%s", NODE_URL, supplyPath);
        final HttpRequest request =
            HttpRequest.newBuilder(URI.create(url)).GET().build();
        final HttpResponse<String> response =
            HTTP_CLIENT.send(request, BodyHandlers.ofString());
        return new BigDecimal(response.body().trim());
    }

    private static String formatSupply(final BigDecimal value) {
        return String.format(Locale.US, "%,.6f", value);
    }

    public static void main(final String[] args) {
        new QueryCurrencySupply().run();
    }

    private void run() {
        System.out.printf("Using node %s%n", NODE_URL);

        try {

            final BigDecimal maximumSupply = fetchSupplyValue("max");
            System.out.printf("Maximum supply: %s XYM%n",
                formatSupply(maximumSupply));

            final BigDecimal totalSupply = fetchSupplyValue("total");
            System.out.printf("Total supply: %s XYM%n",
                formatSupply(totalSupply));

            final BigDecimal circulatingSupply =
                fetchSupplyValue("circulating");
            System.out.printf("Circulating supply: %s XYM%n",
                formatSupply(circulatingSupply));

            final BigDecimal nonCirculatingSupply =
                totalSupply.subtract(circulatingSupply);
            System.out.printf("Non-circulating supply: %s XYM%n",
                formatSupply(nonCirculatingSupply));

            final BigDecimal unmintedSupply =
                maximumSupply.subtract(totalSupply);
            System.out.printf("Unminted supply: %s XYM%n",
                formatSupply(unmintedSupply));
        } catch (final Exception ex) {
            System.out.println(ex.getMessage());
        }
    }
}

Download source

このスニペットでは、 NODE_URL 環境変数を使用してSymbol APIノードを設定します。 値が指定されない場合は、デフォルトのテストネットノードが使用されます。

デフォルトノードはテストネットです

デフォルトのノードはテストネットを指しています。 本番環境の供給量データについては、 NODE_URLメインネットノードに設定してください。 利用可能なメインネットノードのリストについては、symbol.fyi/nodesを参照してください。

コード解説⚓︎

供給量の値の取得⚓︎

    with urllib.request.urlopen(f'{SUPPLY_URL}/max') as response:
        maximum_supply = Decimal(response.read().decode().strip())
    print(f'Maximum supply: {maximum_supply:,.6f} XYM')

    with urllib.request.urlopen(f'{SUPPLY_URL}/total') as response:
        total_supply = Decimal(response.read().decode().strip())
    print(f'Total supply: {total_supply:,.6f} XYM')

    with urllib.request.urlopen(f'{SUPPLY_URL}/circulating') as response:
        circulating_supply = Decimal(response.read().decode().strip())
    print(f'Circulating supply: {circulating_supply:,.6f} XYM')
    const maximumResponse = await fetch(`${NODE_URL}${SUPPLY_PATH}/max`);
    const maximumSupply = toAtomic(await maximumResponse.text());
    console.log(`Maximum supply: ${fmt(maximumSupply)} XYM`);

    const totalResponse = await fetch(`${NODE_URL}${SUPPLY_PATH}/total`);
    const totalSupply = toAtomic(await totalResponse.text());
    console.log(`Total supply: ${fmt(totalSupply)} XYM`);

    const circulatingResponse =
        await fetch(`${NODE_URL}${SUPPLY_PATH}/circulating`);
    const circulatingSupply = toAtomic(await circulatingResponse.text());
    console.log(`Circulating supply: ${fmt(circulatingSupply)} XYM`);
            final BigDecimal maximumSupply = fetchSupplyValue("max");
            System.out.printf("Maximum supply: %s XYM%n",
                formatSupply(maximumSupply));

            final BigDecimal totalSupply = fetchSupplyValue("total");
            System.out.printf("Total supply: %s XYM%n",
                formatSupply(totalSupply));

            final BigDecimal circulatingSupply =
                fetchSupplyValue("circulating");
            System.out.printf("Circulating supply: %s XYM%n",
                formatSupply(circulatingSupply));

各供給量の値は、専用のエンドポイントを通じて利用できます。

これら3つのエンドポイントはすべて、(JSONではなく)プレーンテキストの数値を返します。これらは絶対単位ではなく、すでに小数点以下の桁数を含む全体単位(例: 8999999999.000000 )で表されています。

8323505878.695894 のような供給量の値は16桁ありますが、浮動小数点数が正確に保持できるのは約15桁です。これらの値を浮動小数点数として解析すると、最後の桁が気付かないうちに変わってしまう可能性があります。そのためコードでは、正確な数値型(Pythonでは Decimal 、JavaScriptでは BigInt を使用する toAtomic ヘルパー、Javaでは BigDecimal )を用いて解析と減算を行っています。

注意: 循環供給量はノードに依存します

非循環アカウントのリストは各ノードオペレーターによって(ノードの rest.json ファイル内で)設定されるため、異なるノードが異なる循環供給量の値を報告する可能性があります。 供給量データを統合する場合は、デフォルト設定を持つ信頼できるノードを照会するようにしてください。

追加の指標の導出⚓︎

    non_circulating_supply = total_supply - circulating_supply
    print(f'Non-circulating supply: {non_circulating_supply:,.6f} XYM')

    unminted_supply = maximum_supply - total_supply
    print(f'Unminted supply: {unminted_supply:,.6f} XYM')
    const nonCirculatingSupply = totalSupply - circulatingSupply;
    console.log(
        `Non-circulating supply: ${fmt(nonCirculatingSupply)} XYM`);

    const unmintedSupply = maximumSupply - totalSupply;
    console.log(`Unminted supply: ${fmt(unmintedSupply)} XYM`);
            final BigDecimal nonCirculatingSupply =
                totalSupply.subtract(circulatingSupply);
            System.out.printf("Non-circulating supply: %s XYM%n",
                formatSupply(nonCirculatingSupply));

            final BigDecimal unmintedSupply =
                maximumSupply.subtract(totalSupply);
            System.out.printf("Unminted supply: %s XYM%n",
                formatSupply(unmintedSupply));

3つの値をすべて取得した後、コードは2つの追加の指標を導き出します。

  • Non-circulating (非循環): 総供給量と循環供給量の差。
  • Unminted (未発行): 最大供給量と総供給量の差。今後発行される予定の残りのXYMを表します。

出力⚓︎

以下の出力は、通貨供給量を照会する典型的な実行例を示しています。

1
2
3
4
5
6
Using node https://reference.symboltest.net:3001
Maximum supply: 8,999,999,999.000000 XYM
Total supply: 8,323,505,878.695894 XYM
Circulating supply: 8,323,495,854.693871 XYM
Non-circulating supply: 10,024.002023 XYM
Unminted supply: 676,494,120.304106 XYM

これらの値はテストネットノードからのものであり、メインネットの供給量の数値を反映していません。

出力は、XYMの供給量の完全な内訳を示しています。

  • 最大供給量 (maximum supply) (2行目): XYMのハードキャップです。
  • 総供給量 (total supply) (3行目): すべてのXYMがまだ発行されているわけではないため、最大供給量より少なくなります。
  • 循環供給量 (circulating supply) (4行目): 一部の発行済みXYMは非循環アカウントによって保持されているため、さらに少なくなります。
  • 非循環供給量 (non-circulating supply) (5行目): 総供給量と循環供給量の差を表します。
  • 未発行供給量 (unminted supply) (6行目): インフレーション報酬を通じて徐々に発行される残りのXYMを示しています。

結論⚓︎

このチュートリアルでは、以下の方法を説明しました。

ステップ 関連ドキュメント
最大供給量の取得 /network/currency/supply/max GET
総供給量の取得 /network/currency/supply/total GET
循環供給量の取得 /network/currency/supply/circulating GET
追加の指標の導出 -

次のステップ⚓︎

特定のアカウントのXYM残高を確認するには、アカウント残高の照会 チュートリアルを参照してください。