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  }