github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/entity_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 "regexp" 26 "strconv" 27 28 "github.com/pkg/errors" 29 ) 30 31 // EntityID is an interface for various IDs of entities (Account, Contract, File, etc) 32 type EntityID interface { 33 _IsEntityID() 34 } 35 36 type _ParseAddressResult struct { 37 status int 38 num1 int64 39 num2 int64 40 num3 int64 41 correctChecksum string 42 givenChecksum string 43 noChecksumFormat string 44 withChecksumFormat string 45 } 46 47 func _ChecksumVerify(num int) error { 48 switch num { 49 case 0: 50 return errors.New("Invalid ID: format should look like 0.0.123 or 0.0.123-laujm") 51 case 1: 52 return errors.New("Invalid ID: checksum does not match") 53 case 2: 54 return nil 55 case 3: 56 return nil 57 default: 58 return errors.New("Unrecognized status") 59 } 60 } 61 62 func _ChecksumParseAddress(ledgerID *LedgerID, address string) (_ParseAddressResult, error) { 63 var err error 64 match := regexp.MustCompile(`(0|(?:[1-9]\d*))\.(0|(?:[1-9]\d*))\.(0|(?:[1-9]\d*))(?:-([a-z]{5}))?$`) 65 66 matchArray := match.FindStringSubmatch(address) 67 68 a := make([]int64, len(matchArray)) 69 for i := 1; i < len(matchArray)-1; i++ { 70 a[i], err = strconv.ParseInt(matchArray[i], 10, 64) 71 if err != nil { 72 return _ParseAddressResult{status: 0}, err 73 } 74 } 75 76 ad := fmt.Sprintf("%s.%s.%s", matchArray[1], matchArray[2], matchArray[3]) 77 78 checksum := _CheckChecksum(ledgerID._LedgerIDBytes, ad) 79 80 var status int 81 switch m := matchArray[4]; { 82 case m == "": 83 status = 2 84 case m == checksum: 85 status = 3 86 default: 87 status = 1 88 } 89 90 return _ParseAddressResult{ 91 status: status, 92 num1: a[1], 93 num2: a[2], 94 num3: a[3], 95 correctChecksum: checksum, 96 givenChecksum: matchArray[4], 97 noChecksumFormat: ad, 98 withChecksumFormat: ad + "(" + checksum + ")", 99 }, nil 100 } 101 102 func _CheckChecksum(ledgerID []byte, address string) string { 103 answer := "" 104 digits := make([]int, 0) 105 s0 := 0 106 s1 := 0 107 s := 0 108 sh := 0 109 checksum := 0 110 n := len(address) 111 p3 := 26 * 26 * 26 112 p5 := 26 * 26 * 26 * 26 * 26 113 m := 1000003 114 asciiA := []rune("a")[0] 115 w := 31 116 117 h := make([]byte, len(ledgerID)+6) 118 copy(h[0:len(ledgerID)], ledgerID) 119 120 for _, j := range address { 121 if string(j) == "." { 122 digits = append(digits, 10) 123 } else { 124 processed, _ := strconv.Atoi(string(j)) 125 digits = append(digits, processed) 126 } 127 } 128 129 for i := 0; i < len(digits); i++ { 130 s = (w*s + digits[i]) % p3 131 if i%2 == 0 { 132 s0 = (s0 + digits[i]) % 11 133 } else { 134 s1 = (s1 + digits[i]) % 11 135 } 136 } 137 138 for i := 0; i < len(h); i++ { 139 sh = (w*sh + int(h[i])) % p5 140 } 141 142 checksum = ((((n%5)*11+s0)*11+s1)*p3 + s + sh) % p5 143 checksum = (checksum * m) % p5 144 145 for i := 0; i < 5; i++ { 146 answer = string(asciiA+rune(checksum%26)) + answer 147 checksum /= 26 148 } 149 150 return answer 151 } 152 153 func (id AccountID) _IsEntityID() {} 154 155 // func (id FileID) _IsEntityID() {} 156 // func (id ContractID) _IsEntityID() {}