github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/token_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 // TokenID is the ID for a Hedera token 33 type TokenID struct { 34 Shard uint64 35 Realm uint64 36 Token uint64 37 checksum *string 38 } 39 40 func _TokenIDFromProtobuf(tokenID *services.TokenID) *TokenID { 41 if tokenID == nil { 42 return nil 43 } 44 45 return &TokenID{ 46 Shard: uint64(tokenID.ShardNum), 47 Realm: uint64(tokenID.RealmNum), 48 Token: uint64(tokenID.TokenNum), 49 } 50 } 51 52 func (id *TokenID) _ToProtobuf() *services.TokenID { 53 return &services.TokenID{ 54 ShardNum: int64(id.Shard), 55 RealmNum: int64(id.Realm), 56 TokenNum: int64(id.Token), 57 } 58 } 59 60 // String returns a string representation of the TokenID formatted as `Shard.Realm.TokenID` (for example "0.0.3") 61 func (id TokenID) String() string { 62 return fmt.Sprintf("%d.%d.%d", id.Shard, id.Realm, id.Token) 63 } 64 65 // ToStringWithChecksum returns a string representation of the TokenID formatted as `Shard.Realm.TokenID-Checksum` (for example "0.0.3-abcd") 66 func (id TokenID) ToStringWithChecksum(client Client) (string, error) { 67 if client.GetNetworkName() == nil && client.GetLedgerID() == nil { 68 return "", errNetworkNameMissing 69 } 70 var checksum _ParseAddressResult 71 var err error 72 if client.network.ledgerID != nil { 73 checksum, err = _ChecksumParseAddress(client.GetLedgerID(), fmt.Sprintf("%d.%d.%d", id.Shard, id.Realm, id.Token)) 74 } 75 if err != nil { 76 return "", err 77 } 78 return fmt.Sprintf("%d.%d.%d-%s", id.Shard, id.Realm, id.Token, checksum.correctChecksum), nil 79 } 80 81 // ToBytes returns a byte array representation of the TokenID 82 func (id TokenID) ToBytes() []byte { 83 data, err := protobuf.Marshal(id._ToProtobuf()) 84 if err != nil { 85 return make([]byte, 0) 86 } 87 88 return data 89 } 90 91 // TokenIDFromBytes returns a TokenID from a byte array 92 func TokenIDFromBytes(data []byte) (TokenID, error) { 93 if data == nil { 94 return TokenID{}, errByteArrayNull 95 } 96 pb := services.TokenID{} 97 err := protobuf.Unmarshal(data, &pb) 98 if err != nil { 99 return TokenID{}, err 100 } 101 102 return *_TokenIDFromProtobuf(&pb), nil 103 } 104 105 // NftID constructs an NftID from a TokenID and a serial number 106 func (id *TokenID) Nft(serial int64) NftID { 107 return NftID{ 108 TokenID: *id, 109 SerialNumber: serial, 110 } 111 } 112 113 // TokenIDFromString constructs an TokenID from a string formatted as 114 // `Shard.Realm.TokenID` (for example "0.0.3") 115 func TokenIDFromString(data string) (TokenID, error) { 116 shard, realm, num, checksum, err := _IdFromString(data) 117 if err != nil { 118 return TokenID{}, err 119 } 120 121 return TokenID{ 122 Shard: uint64(shard), 123 Realm: uint64(realm), 124 Token: uint64(num), 125 checksum: checksum, 126 }, nil 127 } 128 129 // Verify that the client has a valid checksum. 130 func (id *TokenID) ValidateChecksum(client *Client) error { 131 if !id._IsZero() && client != nil { 132 var tempChecksum _ParseAddressResult 133 var err error 134 tempChecksum, err = _ChecksumParseAddress(client.GetLedgerID(), fmt.Sprintf("%d.%d.%d", id.Shard, id.Realm, id.Token)) 135 if err != nil { 136 return err 137 } 138 err = _ChecksumVerify(tempChecksum.status) 139 if err != nil { 140 return err 141 } 142 if id.checksum == nil { 143 return errChecksumMissing 144 } 145 if tempChecksum.correctChecksum != *id.checksum { 146 networkName := NetworkNameOther 147 if client.network.ledgerID != nil { 148 networkName, _ = client.network.ledgerID.ToNetworkName() 149 } 150 return errors.New(fmt.Sprintf("network mismatch or wrong checksum given, given checksum: %s, correct checksum %s, network: %s", 151 *id.checksum, 152 tempChecksum.correctChecksum, 153 networkName)) 154 } 155 } 156 157 return nil 158 } 159 160 // Deprecated - use ValidateChecksum instead 161 func (id *TokenID) Validate(client *Client) error { 162 return id.ValidateChecksum(client) 163 } 164 165 // TokenIDFromSolidityAddress constructs a TokenID from a string 166 // representation of a _Solidity address 167 func TokenIDFromSolidityAddress(s string) (TokenID, error) { 168 shard, realm, token, err := _IdFromSolidityAddress(s) 169 if err != nil { 170 return TokenID{}, err 171 } 172 173 return TokenID{ 174 Shard: shard, 175 Realm: realm, 176 Token: token, 177 checksum: nil, 178 }, nil 179 } 180 181 // ToSolidityAddress returns the string representation of the TokenID as a 182 // _Solidity address. 183 func (id TokenID) ToSolidityAddress() string { 184 return _IdToSolidityAddress(id.Shard, id.Realm, id.Token) 185 } 186 187 func (id TokenID) _IsZero() bool { 188 return id.Shard == 0 && id.Realm == 0 && id.Token == 0 189 } 190 191 // equals returns true if this TokenID and the given TokenID are identical 192 func (id TokenID) equals(other TokenID) bool { 193 return id.Shard == other.Shard && id.Realm == other.Realm 194 } 195 196 // Compare compares two TokenIDs 197 func (id TokenID) Compare(given TokenID) int { 198 if id.Shard > given.Shard { //nolint 199 return 1 200 } else if id.Shard < given.Shard { 201 return -1 202 } 203 204 if id.Realm > given.Realm { //nolint 205 return 1 206 } else if id.Realm < given.Realm { 207 return -1 208 } 209 210 if id.Token > given.Token { //nolint 211 return 1 212 } else if id.Token < given.Token { 213 return -1 214 } else { //nolint 215 return 0 216 } 217 }