mkdir go-registry-demo cd go-registry-demo go mod init go-registry-demo CODE_BLOCK: mkdir go-registry-demo cd go-registry-demo go mod init go-registry-demo CODE_BLOCK: mkdir go-registry-demo cd go-registry-demo go mod init go-registry-demo CODE_BLOCK: go get github.com/hashgraph-online/standards-sdk-go@latest CODE_BLOCK: go get github.com/hashgraph-online/standards-sdk-go@latest CODE_BLOCK: go get github.com/hashgraph-online/standards-sdk-go@latest CODE_BLOCK: export HEDERA_ACCOUNT_ID="0.0.xxxxx" export HEDERA_PRIVATE_KEY="302..." export HEDERA_NETWORK="testnet" CODE_BLOCK: export HEDERA_ACCOUNT_ID="0.0.xxxxx" export HEDERA_PRIVATE_KEY="302..." export HEDERA_NETWORK="testnet" CODE_BLOCK: export HEDERA_ACCOUNT_ID="0.0.xxxxx" export HEDERA_PRIVATE_KEY="302..." export HEDERA_NETWORK="testnet" CODE_BLOCK: package main import ( "context" "fmt" "log" "os" "github.com/hashgraph-online/standards-sdk-go/pkg/hcs2" ) func main() { ctx := context.Background() // Initialize the HCS-2 Client // Notice we can pull configuration directly from the environment client, err := hcs2.NewClient(hcs2.ClientConfig{ OperatorAccountID: os.Getenv("HEDERA_ACCOUNT_ID"), OperatorPrivateKey: os.Getenv("HEDERA_PRIVATE_KEY"), Network: "testnet", // Explicitly use testnet }) if err != nil { log.Fatalf("Failed to initialize HCS-2 client: %v", err) } fmt.Println("Successfully initialized HCS-2 Client!") } CODE_BLOCK: package main import ( "context" "fmt" "log" "os" "github.com/hashgraph-online/standards-sdk-go/pkg/hcs2" ) func main() { ctx := context.Background() // Initialize the HCS-2 Client // Notice we can pull configuration directly from the environment client, err := hcs2.NewClient(hcs2.ClientConfig{ OperatorAccountID: os.Getenv("HEDERA_ACCOUNT_ID"), OperatorPrivateKey: os.Getenv("HEDERA_PRIVATE_KEY"), Network: "testnet", // Explicitly use testnet }) if err != nil { log.Fatalf("Failed to initialize HCS-2 client: %v", err) } fmt.Println("Successfully initialized HCS-2 Client!") } CODE_BLOCK: package main import ( "context" "fmt" "log" "os" "github.com/hashgraph-online/standards-sdk-go/pkg/hcs2" ) func main() { ctx := context.Background() // Initialize the HCS-2 Client // Notice we can pull configuration directly from the environment client, err := hcs2.NewClient(hcs2.ClientConfig{ OperatorAccountID: os.Getenv("HEDERA_ACCOUNT_ID"), OperatorPrivateKey: os.Getenv("HEDERA_PRIVATE_KEY"), Network: "testnet", // Explicitly use testnet }) if err != nil { log.Fatalf("Failed to initialize HCS-2 client: %v", err) } fmt.Println("Successfully initialized HCS-2 Client!") } CODE_BLOCK: // ... previous code ... fmt.Println("Creating a new HCS-2 Indexed Registry...") // Create the registry result, err := client.CreateRegistry(ctx, hcs2.CreateRegistryOptions{ RegistryType: hcs2.RegistryTypeIndexed, UseOperatorAsAdmin: true, // We retain administrative control UseOperatorAsSubmit: true, // We must sign future entries }) if err != nil { log.Fatalf("Failed to create registry: %v", err) } topicID := result.TopicID.String() fmt.Printf("✅ Registry created successfully!\nTopic ID: %s\n", topicID) CODE_BLOCK: // ... previous code ... fmt.Println("Creating a new HCS-2 Indexed Registry...") // Create the registry result, err := client.CreateRegistry(ctx, hcs2.CreateRegistryOptions{ RegistryType: hcs2.RegistryTypeIndexed, UseOperatorAsAdmin: true, // We retain administrative control UseOperatorAsSubmit: true, // We must sign future entries }) if err != nil { log.Fatalf("Failed to create registry: %v", err) } topicID := result.TopicID.String() fmt.Printf("✅ Registry created successfully!\nTopic ID: %s\n", topicID) CODE_BLOCK: // ... previous code ... fmt.Println("Creating a new HCS-2 Indexed Registry...") // Create the registry result, err := client.CreateRegistry(ctx, hcs2.CreateRegistryOptions{ RegistryType: hcs2.RegistryTypeIndexed, UseOperatorAsAdmin: true, // We retain administrative control UseOperatorAsSubmit: true, // We must sign future entries }) if err != nil { log.Fatalf("Failed to create registry: %v", err) } topicID := result.TopicID.String() fmt.Printf("✅ Registry created successfully!\nTopic ID: %s\n", topicID) CODE_BLOCK: // ... previous code ... // Let's define the data we want to register // We'll register two physical IoT devices entries := []struct { Index string Data map[string]any }{ { Index: "device-001", Data: map[string]any{"type": "sensor", "status": "active"}, }, { Index: "device-002", Data: map[string]any{"type": "actuator", "status": "offline"}, }, } for _, entry := range entries { fmt.Printf("Registering %s...\n", entry.Index) publishResult, err := client.PublishIndexedEntry(ctx, hcs2.PublishIndexedEntryOptions{ TopicID: topicID, Index: entry.Index, Data: entry.Data, }) if err != nil { log.Fatalf("Failed to publish entry: %v", err) } fmt.Printf("Published entry securely at Sequence #%d\n", publishResult.SequenceNumber) } CODE_BLOCK: // ... previous code ... // Let's define the data we want to register // We'll register two physical IoT devices entries := []struct { Index string Data map[string]any }{ { Index: "device-001", Data: map[string]any{"type": "sensor", "status": "active"}, }, { Index: "device-002", Data: map[string]any{"type": "actuator", "status": "offline"}, }, } for _, entry := range entries { fmt.Printf("Registering %s...\n", entry.Index) publishResult, err := client.PublishIndexedEntry(ctx, hcs2.PublishIndexedEntryOptions{ TopicID: topicID, Index: entry.Index, Data: entry.Data, }) if err != nil { log.Fatalf("Failed to publish entry: %v", err) } fmt.Printf("Published entry securely at Sequence #%d\n", publishResult.SequenceNumber) } CODE_BLOCK: // ... previous code ... // Let's define the data we want to register // We'll register two physical IoT devices entries := []struct { Index string Data map[string]any }{ { Index: "device-001", Data: map[string]any{"type": "sensor", "status": "active"}, }, { Index: "device-002", Data: map[string]any{"type": "actuator", "status": "offline"}, }, } for _, entry := range entries { fmt.Printf("Registering %s...\n", entry.Index) publishResult, err := client.PublishIndexedEntry(ctx, hcs2.PublishIndexedEntryOptions{ TopicID: topicID, Index: entry.Index, Data: entry.Data, }) if err != nil { log.Fatalf("Failed to publish entry: %v", err) } fmt.Printf("Published entry securely at Sequence #%d\n", publishResult.SequenceNumber) } CODE_BLOCK: // ... previous code ... fmt.Println("Fetching current registry state from Hedera Mirror Node...") // Fetch all valid entries for our topic state, err := client.GetIndexedRegistryState(ctx, topicID) if err != nil { log.Fatalf("Failed to fetch state: %v", err) } fmt.Println("\n--- Current Registry State ---") for key, value := range state { fmt.Printf("Key [%s]: %v\n", key, value) } } CODE_BLOCK: // ... previous code ... fmt.Println("Fetching current registry state from Hedera Mirror Node...") // Fetch all valid entries for our topic state, err := client.GetIndexedRegistryState(ctx, topicID) if err != nil { log.Fatalf("Failed to fetch state: %v", err) } fmt.Println("\n--- Current Registry State ---") for key, value := range state { fmt.Printf("Key [%s]: %v\n", key, value) } } CODE_BLOCK: // ... previous code ... fmt.Println("Fetching current registry state from Hedera Mirror Node...") // Fetch all valid entries for our topic state, err := client.GetIndexedRegistryState(ctx, topicID) if err != nil { log.Fatalf("Failed to fetch state: %v", err) } fmt.Println("\n--- Current Registry State ---") for key, value := range state { fmt.Printf("Key [%s]: %v\n", key, value) } }
- Append-Only: A continuous stream of events or records.
- Indexed: A key-value store where later entries can "overwrite" or update the state of previous keys using deterministic indexing.
- AI Agent identity directories
- Decentralized package managers
- Supply chain provenance logs
- Certificate revocation lists
- Go 1.22 or higher installed.
- A Hedera Testnet account (Account ID and Private Key). You can get one from the Hedera Developer Portal.
- Deterministic Memos: The CreateRegistry call automatically formats the memo of the Hedera topic to hcs-2;indexed, signaling to the rest of the ecosystem how to interpret the messages.
- Schema Enforcement: The SDK ensures that messages submitted to the topic strictly adhere to the HCS-2 JSON schema.
- Consensus Targeting: Messages are delivered instantly across the globe with fair-ordering consensus applied by the Hedera validators.
- HCS-14 (Universal Agent IDs): Resolve AI identities.
- Registry Broker: Use the pkg/registrybroker to interact directly with the global Hashgraph Online Registry Broker.