github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/topic_id.go (about)

     1  package hedera
     2  
     3  /*-
     4   *
     5   * Hedera Go SDK
     6   *
     7   * Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
     8   *
     9   * Licensed under the Apache License, Version 2.0 (the "License");
    10   * you may not use this file except in compliance with the License.
    11   * You may obtain a copy of the License at
    12   *
    13   *      http://www.apache.org/licenses/LICENSE-2.0
    14   *
    15   * Unless required by applicable law or agreed to in writing, software
    16   * distributed under the License is distributed on an "AS IS" BASIS,
    17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    18   * See the License for the specific language governing permissions and
    19   * limitations under the License.
    20   *
    21   */
    22  
    23  import (
    24  	"fmt"
    25  
    26  	"github.com/pkg/errors"
    27  
    28  	"github.com/hashgraph/hedera-protobufs-go/services"
    29  	protobuf "google.golang.org/protobuf/proto"
    30  )
    31  
    32  // TopicID is a unique identifier for a topic (used by the  service)
    33  type TopicID struct {
    34  	Shard    uint64
    35  	Realm    uint64
    36  	Topic    uint64
    37  	checksum *string
    38  }
    39  
    40  // TopicIDFromString constructs a TopicID from a string formatted as `Shard.Realm.Topic` (for example "0.0.3")
    41  func TopicIDFromString(data string) (TopicID, error) {
    42  	shard, realm, num, checksum, err := _IdFromString(data)
    43  	if err != nil {
    44  		return TopicID{}, err
    45  	}
    46  
    47  	return TopicID{
    48  		Shard:    uint64(shard),
    49  		Realm:    uint64(realm),
    50  		Topic:    uint64(num),
    51  		checksum: checksum,
    52  	}, nil
    53  }
    54  
    55  // Verify that the client has a valid checksum.
    56  func (id *TopicID) ValidateChecksum(client *Client) error {
    57  	if !id._IsZero() && client != nil {
    58  		tempChecksum, err := _ChecksumParseAddress(client.GetLedgerID(), fmt.Sprintf("%d.%d.%d", id.Shard, id.Realm, id.Topic))
    59  		if err != nil {
    60  			return err
    61  		}
    62  		err = _ChecksumVerify(tempChecksum.status)
    63  		if err != nil {
    64  			return err
    65  		}
    66  		if id.checksum == nil {
    67  			return errChecksumMissing
    68  		}
    69  		if tempChecksum.correctChecksum != *id.checksum {
    70  			networkName := NetworkNameOther
    71  			if client.network.ledgerID != nil {
    72  				networkName, _ = client.network.ledgerID.ToNetworkName()
    73  			}
    74  			return errors.New(fmt.Sprintf("network mismatch or wrong checksum given, given checksum: %s, correct checksum %s, network: %s",
    75  				*id.checksum,
    76  				tempChecksum.correctChecksum,
    77  				networkName))
    78  		}
    79  	}
    80  
    81  	return nil
    82  }
    83  
    84  // Deprecated - use ValidateChecksum instead
    85  func (id *TopicID) Validate(client *Client) error {
    86  	return id.ValidateChecksum(client)
    87  }
    88  
    89  func (id TopicID) _IsZero() bool {
    90  	return id.Shard == 0 && id.Realm == 0 && id.Topic == 0
    91  }
    92  
    93  // String returns the string representation of a TopicID in `Shard.Realm.Topic` (for example "0.0.3")
    94  func (id TopicID) String() string {
    95  	return fmt.Sprintf("%d.%d.%d", id.Shard, id.Realm, id.Topic)
    96  }
    97  
    98  // ToStringWithChecksum returns the string representation of a TopicID in `Shard.Realm.Topic-Checksum` (for example "0.0.3-abcde")
    99  func (id TopicID) ToStringWithChecksum(client Client) (string, error) {
   100  	if client.GetNetworkName() == nil && client.GetLedgerID() == nil {
   101  		return "", errNetworkNameMissing
   102  	}
   103  	var checksum _ParseAddressResult
   104  	var err error
   105  	if client.network.ledgerID != nil {
   106  		checksum, err = _ChecksumParseAddress(client.GetLedgerID(), fmt.Sprintf("%d.%d.%d", id.Shard, id.Realm, id.Topic))
   107  	}
   108  	if err != nil {
   109  		return "", err
   110  	}
   111  	return fmt.Sprintf("%d.%d.%d-%s", id.Shard, id.Realm, id.Topic, checksum.correctChecksum), nil
   112  }
   113  
   114  func (id TopicID) _ToProtobuf() *services.TopicID {
   115  	return &services.TopicID{
   116  		ShardNum: int64(id.Shard),
   117  		RealmNum: int64(id.Realm),
   118  		TopicNum: int64(id.Topic),
   119  	}
   120  }
   121  
   122  func _TopicIDFromProtobuf(topicID *services.TopicID) *TopicID {
   123  	if topicID == nil {
   124  		return nil
   125  	}
   126  
   127  	return &TopicID{
   128  		Shard: uint64(topicID.ShardNum),
   129  		Realm: uint64(topicID.RealmNum),
   130  		Topic: uint64(topicID.TopicNum),
   131  	}
   132  }
   133  
   134  // ToBytes returns a byte array representation of the TopicID
   135  func (id TopicID) ToBytes() []byte {
   136  	data, err := protobuf.Marshal(id._ToProtobuf())
   137  	if err != nil {
   138  		return make([]byte, 0)
   139  	}
   140  
   141  	return data
   142  }
   143  
   144  // TopicIDFromBytes constructs a TopicID from a byte array
   145  func TopicIDFromBytes(data []byte) (TopicID, error) {
   146  	if data == nil {
   147  		return TopicID{}, errByteArrayNull
   148  	}
   149  	pb := services.TopicID{}
   150  	err := protobuf.Unmarshal(data, &pb)
   151  	if err != nil {
   152  		return TopicID{}, err
   153  	}
   154  
   155  	return *_TopicIDFromProtobuf(&pb), nil
   156  }
   157  
   158  // TopicIDFromSolidityAddress constructs an TopicID from a string
   159  // representation of a _Solidity address
   160  func TopicIDFromSolidityAddress(s string) (TopicID, error) {
   161  	shard, realm, topic, err := _IdFromSolidityAddress(s)
   162  	if err != nil {
   163  		return TopicID{}, err
   164  	}
   165  
   166  	return TopicID{
   167  		Shard:    shard,
   168  		Realm:    realm,
   169  		Topic:    topic,
   170  		checksum: nil,
   171  	}, nil
   172  }
   173  
   174  // ToSolidityAddress returns the string representation of the TopicID as a
   175  // _Solidity address.
   176  func (id TopicID) ToSolidityAddress() string {
   177  	return _IdToSolidityAddress(id.Shard, id.Realm, id.Topic)
   178  }