コンテンツにスキップ

ネームスペース情報の取得⚓︎

初級

このチュートリアルでは、 ネームスペースのプロパティと、それが指し示す モザイクまたはアカウントを取得する方法を説明します。

前提条件⚓︎

このチュートリアルはネットワークからデータを読み取るだけです。アカウントは必要ありません。

開始する前に、開発環境のセットアップを済ませておいてください。

完全なコード⚓︎

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

import json
import os
import urllib.request

from symbolchain.symbol.IdGenerator import generate_namespace_path
from symbolchain.symbol.Network import Address

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

NAMESPACE_NAME = os.getenv('NAMESPACE_NAME', 'symbol.xym')
print(f'Namespace name: {NAMESPACE_NAME}')

try:
    # Generate namespace ID from name
    path = generate_namespace_path(NAMESPACE_NAME)
    namespace_id = path[-1]
    namespace_id_hex = f'{namespace_id:016X}'
    print(f'Namespace ID: {namespace_id} (0x{namespace_id_hex})')

    # Fetch namespace information
    namespace_path = f'/namespaces/{namespace_id_hex}'
    print(f'Fetching namespace information from {namespace_path}')
    with urllib.request.urlopen(
        f'{NODE_URL}{namespace_path}') as response:
        response_json = json.loads(response.read().decode())
        ns = response_json['namespace']
        print('Namespace information:')
        reg_type = ns['registrationType']
        print(f'  Registration type: {reg_type}')
        owner_address = Address.from_decoded_address_hex_string(
            ns['ownerAddress'])
        print(f'  Owner address: {owner_address}')
        depth = int(ns['depth'])
        print(f'  Depth: {depth}')
        print(f'  Level 0 ID: {ns["level0"]}')
        if depth >= 2:
            print(f'  Level 1 ID: {ns["level1"]}')
        if depth == 3 and 'level2' in ns:
            print(f'  Level 2 ID: {ns["level2"]}')
        print(f'  Start height: {ns["startHeight"]}')
        end_height = int(ns['endHeight'])
        print(f'  End height: {end_height} (0x{end_height:X})')

        # Display alias information
        alias = ns['alias']
        alias_type = alias['type']
        print(f'  Alias type: {alias_type}')
        if alias_type == 1:
            print(f'  Linked mosaic ID: {alias["mosaicId"]}')
        elif alias_type == 2:
            linked_address = (
                Address.from_decoded_address_hex_string(
                    alias['address']))
            print(f'  Linked address: {linked_address}')
        else:
            print('  No alias linked')

except Exception as e:
    print(e)

Download source

import { Address, generateNamespacePath } from 'symbol-sdk/symbol';

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

const NAMESPACE_NAME = process.env.NAMESPACE_NAME || 'symbol.xym';
console.log('Namespace name:', NAMESPACE_NAME);

try {
    // Generate namespace ID from name
    const path = generateNamespacePath(NAMESPACE_NAME);
    const namespaceId = path[path.length - 1];
    const namespaceIdHex = namespaceId.toString(16)
        .toUpperCase().padStart(16, '0');
    console.log('Namespace ID:', `${namespaceId} (0x${namespaceIdHex})`);

    // Fetch namespace information
    const namespacePath = `/namespaces/${namespaceIdHex}`;
    console.log('Fetching namespace information from', namespacePath);
    const namespaceResponse = await fetch(`${NODE_URL}${namespacePath}`);
    if (!namespaceResponse.ok) {
        throw new Error(
            `HTTP error! status: ${namespaceResponse.status}`);
    }

    const namespaceJSON = await namespaceResponse.json();
    const ns = namespaceJSON.namespace;
    console.log('Namespace information:');
    console.log('  Registration type:', ns.registrationType);
    const ownerAddress = Address.fromDecodedAddressHexString(
        ns.ownerAddress);
    console.log('  Owner address:', ownerAddress.toString());
    const depth = ns.depth;
    console.log('  Depth:', depth);
    console.log('  Level 0 ID:', ns.level0);
    if (2 <= depth)
        console.log('  Level 1 ID:', ns.level1);
    if (3 === depth && ns.level2)
        console.log('  Level 2 ID:', ns.level2);
    console.log('  Start height:', ns.startHeight);
    const endHeight = BigInt(ns.endHeight);
    console.log('  End height:',
        `${endHeight} (0x${endHeight.toString(16).toUpperCase()})`);

    // Display alias information
    const alias = ns.alias;
    console.log('  Alias type:', alias.type);
    if (1 === alias.type) {
        console.log('  Linked mosaic ID:', alias.mosaicId);
    } else if (2 === alias.type) {
        const linkedAddress = Address.fromDecodedAddressHexString(
            alias.address);
        console.log('  Linked address:', linkedAddress.toString());
    } else {
        console.log('  No alias linked');
    }
} catch (e) {
    console.error(e.message);
}

Download source

//JAVA 21+
//DEPS org.symbol:symbol-sdk:3.3.1

import java.io.IOException;
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.List;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.symbol.sdk.symbol.Address;
import org.symbol.sdk.symbol.IdGenerator;

public final class GetNamespaceInfo {
    private static final ObjectMapper JSON_MAPPER = new ObjectMapper();

    private static final HttpClient HTTP_CLIENT =
        HttpClient.newHttpClient();

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

    public static void main(final String[] args) {
        try {
            new GetNamespaceInfo().run();
        } catch (final Exception ex) {
            System.out.println(null == ex.getMessage()
                ? ex.toString()
                : ex.getMessage());
        }
    }

    private void run() throws IOException, InterruptedException {
        System.out.printf("Using node %s%n", nodeUrl);

        final String namespaceName = System.getenv().getOrDefault(
            "NAMESPACE_NAME", "symbol.xym");
        System.out.printf("Namespace name: %s%n", namespaceName);

        // Generate namespace ID from name
        final List<Long> path = IdGenerator.generateNamespacePath(
            namespaceName);
        final long namespaceId = path.get(path.size() - 1);
        final String namespaceIdHex = "%016X".formatted(namespaceId);
        System.out.printf("Namespace ID: %s (0x%s)%n",
            Long.toUnsignedString(namespaceId), namespaceIdHex);

        // Fetch namespace information
        final String namespacePath = "/namespaces/" + namespaceIdHex;
        System.out.printf("Fetching namespace information from %s%n",
            namespacePath);
        final HttpRequest namespaceRequest = HttpRequest.newBuilder(
            URI.create(nodeUrl + namespacePath)).GET().build();
        final HttpResponse<String> namespaceResponse = HTTP_CLIENT.send(
            namespaceRequest, BodyHandlers.ofString());
        final JsonNode ns = JSON_MAPPER.readTree(
            namespaceResponse.body()).get("namespace");
        System.out.println("Namespace information:");
        System.out.printf("  Registration type: %s%n",
            ns.get("registrationType").asText());
        final Address ownerAddress = Address
            .fromDecodedAddressHexString(ns.get("ownerAddress").asText());
        System.out.printf("  Owner address: %s%n", ownerAddress);
        final int depth = ns.get("depth").asInt();
        System.out.printf("  Depth: %d%n", depth);
        System.out.printf("  Level 0 ID: %s%n",
            ns.get("level0").asText());
        if (2 <= depth)
            System.out.printf("  Level 1 ID: %s%n",
                ns.get("level1").asText());
        if (3 == depth && ns.has("level2"))
            System.out.printf("  Level 2 ID: %s%n",
                ns.get("level2").asText());
        System.out.printf("  Start height: %s%n",
            ns.get("startHeight").asText());
        final long endHeight = Long.parseUnsignedLong(
            ns.get("endHeight").asText());
        System.out.printf("  End height: %s (0x%X)%n",
            Long.toUnsignedString(endHeight), endHeight);

        // Display alias information
        final JsonNode alias = ns.get("alias");
        final int aliasType = alias.get("type").asInt();
        System.out.printf("  Alias type: %d%n", aliasType);
        if (1 == aliasType) {
            System.out.printf("  Linked mosaic ID: %s%n",
                alias.get("mosaicId").asText());
        } else if (2 == aliasType) {
            final Address linkedAddress = Address
                .fromDecodedAddressHexString(
                    alias.get("address").asText());
            System.out.printf("  Linked address: %s%n", linkedAddress);
        } else {
            System.out.println("  No alias linked");
        }
    }
}

Download source

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

NAMESPACE_NAME 環境変数は、照会するネームスペースを指定します。 設定されていない場合は、ネットワークのネイティブ通貨である XYM にリンクされたネームスペース symbol.xym がデフォルトで設定されます。

コード解説⚓︎

ネームスペースIDの生成⚓︎

    # Generate namespace ID from name
    path = generate_namespace_path(NAMESPACE_NAME)
    namespace_id = path[-1]
    namespace_id_hex = f'{namespace_id:016X}'
    print(f'Namespace ID: {namespace_id} (0x{namespace_id_hex})')
    // Generate namespace ID from name
    const path = generateNamespacePath(NAMESPACE_NAME);
    const namespaceId = path[path.length - 1];
    const namespaceIdHex = namespaceId.toString(16)
        .toUpperCase().padStart(16, '0');
    console.log('Namespace ID:', `${namespaceId} (0x${namespaceIdHex})`);
        // Generate namespace ID from name
        final List<Long> path = IdGenerator.generateNamespacePath(
            namespaceName);
        final long namespaceId = path.get(path.size() - 1);
        final String namespaceIdHex = "%016X".formatted(namespaceId);
        System.out.printf("Namespace ID: %s (0x%s)%n",
            Long.toUnsignedString(namespaceId), namespaceIdHex);

ネームスペースIDは、 を使用して、ネームスペース名からローカルで計算されます。 この関数は、 symbol.xym のような完全修飾名を受け取り、それを . で分割し、階層の各レベルのネームスペースIDの配列を返します。 最後の要素は、最も深いネームスペースのIDです。

ネームスペース情報の取得⚓︎

    # Fetch namespace information
    namespace_path = f'/namespaces/{namespace_id_hex}'
    print(f'Fetching namespace information from {namespace_path}')
    with urllib.request.urlopen(
        f'{NODE_URL}{namespace_path}') as response:
        response_json = json.loads(response.read().decode())
        ns = response_json['namespace']
        print('Namespace information:')
        reg_type = ns['registrationType']
        print(f'  Registration type: {reg_type}')
        owner_address = Address.from_decoded_address_hex_string(
            ns['ownerAddress'])
        print(f'  Owner address: {owner_address}')
        depth = int(ns['depth'])
        print(f'  Depth: {depth}')
        print(f'  Level 0 ID: {ns["level0"]}')
        if depth >= 2:
            print(f'  Level 1 ID: {ns["level1"]}')
        if depth == 3 and 'level2' in ns:
            print(f'  Level 2 ID: {ns["level2"]}')
        print(f'  Start height: {ns["startHeight"]}')
        end_height = int(ns['endHeight'])
        print(f'  End height: {end_height} (0x{end_height:X})')
    // Fetch namespace information
    const namespacePath = `/namespaces/${namespaceIdHex}`;
    console.log('Fetching namespace information from', namespacePath);
    const namespaceResponse = await fetch(`${NODE_URL}${namespacePath}`);
    if (!namespaceResponse.ok) {
        throw new Error(
            `HTTP error! status: ${namespaceResponse.status}`);
    }

    const namespaceJSON = await namespaceResponse.json();
    const ns = namespaceJSON.namespace;
    console.log('Namespace information:');
    console.log('  Registration type:', ns.registrationType);
    const ownerAddress = Address.fromDecodedAddressHexString(
        ns.ownerAddress);
    console.log('  Owner address:', ownerAddress.toString());
    const depth = ns.depth;
    console.log('  Depth:', depth);
    console.log('  Level 0 ID:', ns.level0);
    if (2 <= depth)
        console.log('  Level 1 ID:', ns.level1);
    if (3 === depth && ns.level2)
        console.log('  Level 2 ID:', ns.level2);
    console.log('  Start height:', ns.startHeight);
    const endHeight = BigInt(ns.endHeight);
    console.log('  End height:',
        `${endHeight} (0x${endHeight.toString(16).toUpperCase()})`);
        // Fetch namespace information
        final String namespacePath = "/namespaces/" + namespaceIdHex;
        System.out.printf("Fetching namespace information from %s%n",
            namespacePath);
        final HttpRequest namespaceRequest = HttpRequest.newBuilder(
            URI.create(nodeUrl + namespacePath)).GET().build();
        final HttpResponse<String> namespaceResponse = HTTP_CLIENT.send(
            namespaceRequest, BodyHandlers.ofString());
        final JsonNode ns = JSON_MAPPER.readTree(
            namespaceResponse.body()).get("namespace");
        System.out.println("Namespace information:");
        System.out.printf("  Registration type: %s%n",
            ns.get("registrationType").asText());
        final Address ownerAddress = Address
            .fromDecodedAddressHexString(ns.get("ownerAddress").asText());
        System.out.printf("  Owner address: %s%n", ownerAddress);
        final int depth = ns.get("depth").asInt();
        System.out.printf("  Depth: %d%n", depth);
        System.out.printf("  Level 0 ID: %s%n",
            ns.get("level0").asText());
        if (2 <= depth)
            System.out.printf("  Level 1 ID: %s%n",
                ns.get("level1").asText());
        if (3 == depth && ns.has("level2"))
            System.out.printf("  Level 2 ID: %s%n",
                ns.get("level2").asText());
        System.out.printf("  Start height: %s%n",
            ns.get("startHeight").asText());
        final long endHeight = Long.parseUnsignedLong(
            ns.get("endHeight").asText());
        System.out.printf("  End height: %s (0x%X)%n",
            Long.toUnsignedString(endHeight), endHeight);

/namespaces/{namespaceId} GET エンドポイントは、以下のネームスペースの現在のプロパティを取得します。

  • Registration type (登録タイプ): 値 0 は ルートネームスペースを示し、 1 は サブネームスペース を示します。

  • Owner address (所有者アドレス): ネームスペースを登録したアカウント。

  • Depth (深さ): ネームスペース階層のレベル数。 例えば、 foo の深さは 1 、 foo.bar の深さは 2 、 foo.bar.baz の深さは 3 です。

  • Levels (レベル): 階層の各レベルのネームスペースID。 level0 は常にルートネームスペースIDです。より深い階層の場合は level1 および level2 が表示されます。

  • Start and end heights (開始および終了ブロック高): ネームスペースが有効な ブロック の範囲。

エイリアスの確認⚓︎

        # Display alias information
        alias = ns['alias']
        alias_type = alias['type']
        print(f'  Alias type: {alias_type}')
        if alias_type == 1:
            print(f'  Linked mosaic ID: {alias["mosaicId"]}')
        elif alias_type == 2:
            linked_address = (
                Address.from_decoded_address_hex_string(
                    alias['address']))
            print(f'  Linked address: {linked_address}')
        else:
            print('  No alias linked')
    // Display alias information
    const alias = ns.alias;
    console.log('  Alias type:', alias.type);
    if (1 === alias.type) {
        console.log('  Linked mosaic ID:', alias.mosaicId);
    } else if (2 === alias.type) {
        const linkedAddress = Address.fromDecodedAddressHexString(
            alias.address);
        console.log('  Linked address:', linkedAddress.toString());
    } else {
        console.log('  No alias linked');
    }
        // Display alias information
        final JsonNode alias = ns.get("alias");
        final int aliasType = alias.get("type").asInt();
        System.out.printf("  Alias type: %d%n", aliasType);
        if (1 == aliasType) {
            System.out.printf("  Linked mosaic ID: %s%n",
                alias.get("mosaicId").asText());
        } else if (2 == aliasType) {
            final Address linkedAddress = Address
                .fromDecodedAddressHexString(
                    alias.get("address").asText());
            System.out.printf("  Linked address: %s%n", linkedAddress);
        } else {
            System.out.println("  No alias linked");
        }

ネームスペース階層の各レベルは、独自のエイリアスを持つことができる独立したネームスペースです。 レスポンスには、照会されたレベルのエイリアス情報が含まれており、モザイクまたはアカウントのどちらにリンクされているかを示します。

  • Alias type 0 (エイリアスタイプ 0): エイリアスはリンクされていません。
  • Alias type 1 (エイリアスタイプ 1): ネームスペースはモザイクにリンクされています。レスポンスにはリンクされた モザイクID が含まれます。
  • Alias type 2 (エイリアスタイプ 2): ネームスペースはアカウントにリンクされています。レスポンスにはリンクされた アドレス が含まれます。

出力⚓︎

以下に示す出力は、テストネット上の symbol.xym ネームスペースを照会する、プログラムの典型的な実行結果に対応しています。

Using node https://reference.symboltest.net:3001
Namespace name: symbol.xym
Namespace ID: 16666583871264174062 (0xE74B99BA41F4AFEE)
Fetching namespace information from /namespaces/E74B99BA41F4AFEE
Namespace information:
  Registration type: 1
  Owner address: TCEUGLPCMO5Y72EEISSNUKGTMCN5RO4PVYMK5FI
  Depth: 2
  Level 0 ID: A95F1F8A96159516
  Level 1 ID: E74B99BA41F4AFEE
  Start height: 1
  End height: 18446744073709551615 (0xFFFFFFFFFFFFFFFF)
  Alias type: 1
  Linked mosaic ID: 72C0212E67A08BCE

出力の主なポイント:

  • Namespace ID (3行目): symbol.xym に対して計算されたIDは 0xE74B99BA41F4AFEE です。

  • Registration type (6行目): 値 1 は、これがサブネームスペース( symbol の子)であることを確認します。

  • Owner address (7行目): symbol ネームスペース階層を登録したアカウント。

  • Depth (8行目): 値 2 は、2段階の階層( symbol (レベル0)と xym (レベル1))であることを示します。

  • Level IDs (9-10行目): level0 はルートの symbol ネームスペースID( A95F1F8A96159516 )であり、 level1 は xym サブネームスペースID( E74B99BA41F4AFEE )です。 最後のレベルIDは3行目のネームスペースIDと一致しており、照会されているネームスペースであることが確認できます。

  • End height (12行目): 値 18446744073709551615 ( 0xFFFFFFFFFFFFFFFF )は、このネームスペースの有効期限が決して切れないことを意味します。

  • Alias (13-14行目): エイリアスタイプ 1 は、ネームスペースがXYMモザイク( 72C0212E67A08BCE )にリンクされていることを確認します。

結論⚓︎

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

ステップ 関連ドキュメント
ネームスペースIDの生成
ネームスペースプロパティの取得 /namespaces/{namespaceId} GET
ネームスペースエイリアスの確認 /namespaces/{namespaceId} GET