github.com/turingchain2020/turingchain@v1.1.21/common/address/address.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package address 计算地址相关的函数 6 package address 7 8 import ( 9 "bytes" 10 "crypto/sha256" 11 "encoding/hex" 12 "errors" 13 "unsafe" 14 15 "github.com/turingchain2020/turingchain/common" 16 "github.com/decred/base58" 17 lru "github.com/hashicorp/golang-lru" 18 ) 19 20 var addrSeed = []byte("address seed bytes for public key") 21 var addressCache *lru.Cache 22 var pubkey2AddrCache *lru.Cache 23 var checkAddressCache *lru.Cache 24 var multisignCache *lru.Cache 25 var multiCheckAddressCache *lru.Cache 26 var execPubKeyCache *lru.Cache 27 28 // ErrCheckVersion : 29 var ErrCheckVersion = errors.New("check version error") 30 31 //ErrCheckChecksum : 32 var ErrCheckChecksum = errors.New("Address Checksum error") 33 34 //ErrAddressChecksum : 35 var ErrAddressChecksum = errors.New("address checksum error") 36 37 //MaxExecNameLength 执行器名最大长度 38 const MaxExecNameLength = 100 39 40 //NormalVer 普通地址的版本号 41 var NormalVer byte 42 43 //MultiSignVer 多重签名地址的版本号 44 var MultiSignVer byte = 5 45 46 func init() { 47 var err error 48 multisignCache, err = lru.New(10240) 49 if err != nil { 50 panic(err) 51 } 52 pubkey2AddrCache, err = lru.New(10240) 53 if err != nil { 54 panic(err) 55 } 56 addressCache, err = lru.New(10240) 57 if err != nil { 58 panic(err) 59 } 60 checkAddressCache, err = lru.New(10240) 61 if err != nil { 62 panic(err) 63 } 64 multiCheckAddressCache, err = lru.New(10240) 65 if err != nil { 66 panic(err) 67 } 68 execPubKeyCache, err = lru.New(10240) 69 if err != nil { 70 panic(err) 71 } 72 } 73 74 //ExecAddress 计算量有点大,做一次cache 75 func ExecAddress(name string) string { 76 if value, ok := addressCache.Get(name); ok { 77 return value.(string) 78 } 79 addr := GetExecAddress(name) 80 addrstr := addr.String() 81 addressCache.Add(name, addrstr) 82 return addrstr 83 } 84 85 //MultiSignAddress create a multi sign address 86 func MultiSignAddress(pubkey []byte) string { 87 skey := *(*string)(unsafe.Pointer(&pubkey)) 88 if value, ok := multisignCache.Get(skey); ok { 89 return value.(string) 90 } 91 addr := HashToAddress(MultiSignVer, pubkey) 92 addrstr := addr.String() 93 multisignCache.Add(string(pubkey), addrstr) 94 return addrstr 95 } 96 97 //ExecPubKey 计算公钥 98 func ExecPubKey(name string) []byte { 99 if len(name) > MaxExecNameLength { 100 panic("name too long") 101 } 102 if value, ok := execPubKeyCache.Get(name); ok { 103 return value.([]byte) 104 } 105 var bname [200]byte 106 buf := append(bname[:0], addrSeed...) 107 buf = append(buf, []byte(name)...) 108 hash := common.Sha2Sum(buf) 109 execPubKeyCache.Add(name, hash) 110 return hash[:] 111 } 112 113 //GetExecAddress 获取地址 114 func GetExecAddress(name string) *Address { 115 hash := ExecPubKey(name) 116 addr := PubKeyToAddress(hash[:]) 117 return addr 118 } 119 120 //PubKeyToAddress 公钥转为地址 121 func PubKeyToAddress(in []byte) *Address { 122 return HashToAddress(NormalVer, in) 123 } 124 125 //PubKeyToAddr 公钥转为地址 126 func PubKeyToAddr(in []byte) string { 127 instr := *(*string)(unsafe.Pointer(&in)) 128 if value, ok := pubkey2AddrCache.Get(instr); ok { 129 return value.(string) 130 } 131 addr := HashToAddress(NormalVer, in).String() 132 pubkey2AddrCache.Add(string(in), addr) 133 return addr 134 } 135 136 //HashToAddress hash32 to address 137 func HashToAddress(version byte, in []byte) *Address { 138 a := new(Address) 139 a.Pubkey = make([]byte, len(in)) 140 copy(a.Pubkey[:], in[:]) 141 a.Version = version 142 a.SetBytes(common.Rimp160(in)) 143 return a 144 } 145 146 func checksum(input []byte) (cksum [4]byte) { 147 h := sha256.Sum256(input) 148 h2 := sha256.Sum256(h[:]) 149 copy(cksum[:], h2[:4]) 150 return 151 } 152 153 func checkAddress(ver byte, addr string) (e error) { 154 155 dec := base58.Decode(addr) 156 if dec == nil { 157 e = errors.New("Cannot decode b58 string '" + addr + "'") 158 checkAddressCache.Add(addr, e) 159 return 160 } 161 if len(dec) < 25 { 162 e = errors.New("Address too short " + hex.EncodeToString(dec)) 163 checkAddressCache.Add(addr, e) 164 return 165 } 166 //version 的错误优先 167 if dec[0] != ver { 168 e = ErrCheckVersion 169 return 170 } 171 //需要兼容以前的错误(以前的错误,是一种特殊的情况) 172 if len(dec) == 25 { 173 sh := common.Sha2Sum(dec[0:21]) 174 if !bytes.Equal(sh[:4], dec[21:25]) { 175 e = ErrCheckChecksum 176 return 177 } 178 } 179 var cksum [4]byte 180 copy(cksum[:], dec[len(dec)-4:]) 181 //新的错误: 这个错误用一种新的错误标记 182 if checksum(dec[:len(dec)-4]) != cksum { 183 e = ErrAddressChecksum 184 } 185 return e 186 } 187 188 //CheckMultiSignAddress 检查多重签名地址的有效性 189 func CheckMultiSignAddress(addr string) (e error) { 190 if value, ok := multiCheckAddressCache.Get(addr); ok { 191 if value == nil { 192 return nil 193 } 194 return value.(error) 195 } 196 e = checkAddress(MultiSignVer, addr) 197 multiCheckAddressCache.Add(addr, e) 198 return 199 } 200 201 //CheckAddress 检查地址 202 func CheckAddress(addr string) (e error) { 203 if value, ok := checkAddressCache.Get(addr); ok { 204 if value == nil { 205 return nil 206 } 207 return value.(error) 208 } 209 e = checkAddress(NormalVer, addr) 210 checkAddressCache.Add(addr, e) 211 return 212 } 213 214 //NewAddrFromString new 地址 215 func NewAddrFromString(hs string) (a *Address, e error) { 216 dec := base58.Decode(hs) 217 if dec == nil { 218 e = errors.New("Cannot decode b58 string '" + hs + "'") 219 return 220 } 221 if len(dec) < 25 { 222 e = errors.New("Address too short " + hex.EncodeToString(dec)) 223 return 224 } 225 if len(dec) == 25 { 226 sh := common.Sha2Sum(dec[0:21]) 227 if !bytes.Equal(sh[:4], dec[21:25]) { 228 e = ErrCheckChecksum 229 } else { 230 a = new(Address) 231 a.Version = dec[0] 232 copy(a.Hash160[:], dec[1:21]) 233 a.Checksum = make([]byte, 4) 234 copy(a.Checksum, dec[21:25]) 235 a.Enc58str = hs 236 } 237 } 238 return 239 } 240 241 //Address 地址 242 type Address struct { 243 Version byte 244 Hash160 [20]byte // For a stealth address: it's HASH160 245 Checksum []byte // Unused for a stealth address 246 Pubkey []byte // Unused for a stealth address 247 Enc58str string 248 } 249 250 //SetBytes 设置地址的bytes 251 func (a *Address) SetBytes(b []byte) { 252 copy(a.Hash160[:], b) 253 } 254 255 func (a *Address) String() string { 256 if a.Enc58str == "" { 257 var ad [25]byte 258 ad[0] = a.Version 259 copy(ad[1:21], a.Hash160[:]) 260 if a.Checksum == nil { 261 sh := common.Sha2Sum(ad[0:21]) 262 a.Checksum = make([]byte, 4) 263 copy(a.Checksum, sh[:4]) 264 } 265 copy(ad[21:25], a.Checksum[:]) 266 a.Enc58str = base58.Encode(ad[:]) 267 } 268 return a.Enc58str 269 } 270 271 //SetNormalAddrVer 根据配置设置生成普通地址的version版本号,默认是0 272 func SetNormalAddrVer(ver byte) { 273 if MultiSignVer == ver { 274 panic("the version of the normal address conflicts with the version of the multi-signature address!") 275 276 } 277 NormalVer = ver 278 }