github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/delegatable_contract_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 "encoding/hex" 25 "fmt" 26 27 "github.com/hashgraph/hedera-protobufs-go/services" 28 "github.com/pkg/errors" 29 protobuf "google.golang.org/protobuf/proto" 30 ) 31 32 // ContractID is the ID for a Hedera smart contract 33 type DelegatableContractID struct { 34 Shard uint64 35 Realm uint64 36 Contract uint64 37 EvmAddress []byte 38 checksum *string 39 } 40 41 // DelegatableContractIDFromString constructs a DelegatableContractID from a string formatted as `Shard.Realm.Contract` (for example "0.0.3") 42 func DelegatableContractIDFromString(data string) (DelegatableContractID, error) { 43 shard, realm, num, checksum, evm, err := _ContractIDFromString(data) 44 if err != nil { 45 return DelegatableContractID{}, err 46 } 47 48 if num == -1 { 49 return DelegatableContractID{ 50 Shard: uint64(shard), 51 Realm: uint64(realm), 52 Contract: 0, 53 EvmAddress: evm, 54 checksum: checksum, 55 }, nil 56 } 57 58 return DelegatableContractID{ 59 Shard: uint64(shard), 60 Realm: uint64(realm), 61 Contract: uint64(num), 62 EvmAddress: nil, 63 checksum: checksum, 64 }, nil 65 } 66 67 // Verify that the client has a valid checksum. 68 func (id *DelegatableContractID) ValidateChecksum(client *Client) error { 69 if !id._IsZero() && client != nil { 70 var tempChecksum _ParseAddressResult 71 var err error 72 if client.network.ledgerID != nil { 73 tempChecksum, err = _ChecksumParseAddress(client.GetLedgerID(), fmt.Sprintf("%d.%d.%d", id.Shard, id.Realm, id.Contract)) 74 } 75 if err != nil { 76 return err 77 } 78 err = _ChecksumVerify(tempChecksum.status) 79 if err != nil { 80 return err 81 } 82 if id.checksum == nil { 83 return errChecksumMissing 84 } 85 if tempChecksum.correctChecksum != *id.checksum { 86 networkName := NetworkNameOther 87 if client.network.ledgerID != nil { 88 networkName, _ = client.network.ledgerID.ToNetworkName() 89 } 90 return errors.New(fmt.Sprintf("network mismatch or wrong checksum given, given checksum: %s, correct checksum %s, network: %s", 91 *id.checksum, 92 tempChecksum.correctChecksum, 93 networkName)) 94 } 95 } 96 97 return nil 98 } 99 100 // DelegatableContractIDFromEvmAddress constructs a DelegatableContractID from a string representation of a _Solidity address 101 func DelegatableContractIDFromEvmAddress(shard uint64, realm uint64, evmAddress string) (DelegatableContractID, error) { 102 temp, err := hex.DecodeString(evmAddress) 103 if err != nil { 104 return DelegatableContractID{}, err 105 } 106 return DelegatableContractID{ 107 Shard: shard, 108 Realm: realm, 109 Contract: 0, 110 EvmAddress: temp, 111 checksum: nil, 112 }, nil 113 } 114 115 // DelegatableContractIDFromSolidityAddress constructs a DelegatableContractID from a string representation of a _Solidity address 116 // Does not populate DelegatableContractID.EvmAddress 117 func DelegatableContractIDFromSolidityAddress(s string) (DelegatableContractID, error) { 118 shard, realm, contract, err := _IdFromSolidityAddress(s) 119 if err != nil { 120 return DelegatableContractID{}, err 121 } 122 123 return DelegatableContractID{ 124 Shard: shard, 125 Realm: realm, 126 Contract: contract, 127 }, nil 128 } 129 130 // String returns the string representation of a DelegatableContractID formatted as `Shard.Realm.Contract` (for example "0.0.3") 131 func (id DelegatableContractID) String() string { 132 if len(id.EvmAddress) > 0 { 133 temp := hex.EncodeToString(id.EvmAddress) 134 return fmt.Sprintf("%d.%d.%s", id.Shard, id.Realm, temp) 135 } 136 return fmt.Sprintf("%d.%d.%d", id.Shard, id.Realm, id.Contract) 137 } 138 139 // ToStringWithChecksum returns the string representation of a DelegatableContractID formatted as `Shard.Realm.Contract-Checksum` (for example "0.0.3-abcde") 140 func (id DelegatableContractID) ToStringWithChecksum(client Client) (string, error) { 141 if id.EvmAddress != nil { 142 return "", errors.New("EvmAddress doesn't support checksums") 143 } 144 if client.GetNetworkName() == nil && client.GetLedgerID() == nil { 145 return "", errNetworkNameMissing 146 } 147 var checksum _ParseAddressResult 148 var err error 149 if client.network.ledgerID != nil { 150 checksum, err = _ChecksumParseAddress(client.GetLedgerID(), fmt.Sprintf("%d.%d.%d", id.Shard, id.Realm, id.Contract)) 151 } 152 if err != nil { 153 return "", err 154 } 155 156 return fmt.Sprintf("%d.%d.%d-%s", id.Shard, id.Realm, id.Contract, checksum.correctChecksum), nil 157 } 158 159 // ToSolidityAddress returns the string representation of the DelegatableContractID as a _Solidity address. 160 func (id DelegatableContractID) ToSolidityAddress() string { 161 return _IdToSolidityAddress(id.Shard, id.Realm, id.Contract) 162 } 163 164 func (id DelegatableContractID) _ToProtobuf() *services.ContractID { 165 resultID := services.ContractID{ 166 ShardNum: int64(id.Shard), 167 RealmNum: int64(id.Realm), 168 } 169 170 if id.EvmAddress != nil { 171 resultID.Contract = &services.ContractID_EvmAddress{EvmAddress: id.EvmAddress} 172 return &resultID 173 } 174 175 resultID.Contract = &services.ContractID_ContractNum{ContractNum: int64(id.Contract)} 176 177 return &resultID 178 } 179 180 func _DelegatableContractIDFromProtobuf(contractID *services.ContractID) *DelegatableContractID { 181 if contractID == nil { 182 return nil 183 } 184 resultID := DelegatableContractID{ 185 Shard: uint64(contractID.ShardNum), 186 Realm: uint64(contractID.RealmNum), 187 } 188 189 switch id := contractID.Contract.(type) { 190 case *services.ContractID_ContractNum: 191 resultID.Contract = uint64(id.ContractNum) 192 resultID.EvmAddress = nil 193 return &resultID 194 case *services.ContractID_EvmAddress: 195 resultID.EvmAddress = id.EvmAddress 196 resultID.Contract = 0 197 return &resultID 198 default: 199 return &resultID 200 } 201 } 202 203 func (id DelegatableContractID) _IsZero() bool { 204 return id.Shard == 0 && id.Realm == 0 && id.Contract == 0 205 } 206 207 func (id DelegatableContractID) _ToProtoKey() *services.Key { 208 return &services.Key{Key: &services.Key_ContractID{ContractID: id._ToProtobuf()}} 209 } 210 211 // ToBytes returns a byte array representation of the DelegatableContractID 212 func (id DelegatableContractID) ToBytes() []byte { 213 data, err := protobuf.Marshal(id._ToProtobuf()) 214 if err != nil { 215 return make([]byte, 0) 216 } 217 218 return data 219 } 220 221 // DelegatableContractIDFromBytes returns a DelegatableContractID generated from a byte array 222 func DelegatableContractIDFromBytes(data []byte) (DelegatableContractID, error) { 223 pb := services.ContractID{} 224 err := protobuf.Unmarshal(data, &pb) 225 if err != nil { 226 return DelegatableContractID{}, err 227 } 228 229 return *_DelegatableContractIDFromProtobuf(&pb), nil 230 }