github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/common/types.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2015 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package common 26 27 import ( 28 "database/sql/driver" 29 "encoding/hex" 30 "encoding/json" 31 "fmt" 32 "math/big" 33 "math/rand" 34 "reflect" 35 "strings" 36 37 "github.com/ethereum/go-ethereum/common/hexutil" 38 "github.com/ethereum/go-ethereum/crypto/sha3" 39 ) 40 41 //哈希和地址的长度(字节)。 42 const ( 43 //hash length是哈希的预期长度 44 HashLength = 32 45 //AddressLength是地址的预期长度 46 AddressLength = 20 47 ) 48 49 var ( 50 hashT = reflect.TypeOf(Hash{}) 51 addressT = reflect.TypeOf(Address{}) 52 ) 53 54 //hash表示任意数据的32字节keccak256哈希。 55 type Hash [HashLength]byte 56 57 //bytestohash将b设置为hash。 58 //如果b大于len(h),b将从左侧裁剪。 59 func BytesToHash(b []byte) Hash { 60 var h Hash 61 h.SetBytes(b) 62 return h 63 } 64 65 //bigtohash将b的字节表示形式设置为hash。 66 //如果b大于len(h),b将从左侧裁剪。 67 func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) } 68 69 //hextohash将s的字节表示形式设置为hash。 70 //如果b大于len(h),b将从左侧裁剪。 71 func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) } 72 73 //Bytes获取基础哈希的字节表示形式。 74 func (h Hash) Bytes() []byte { return h[:] } 75 76 //big将哈希转换为大整数。 77 func (h Hash) Big() *big.Int { return new(big.Int).SetBytes(h[:]) } 78 79 // 80 func (h Hash) Hex() string { return hexutil.Encode(h[:]) } 81 82 //terminalString实现log.terminalStringer,为控制台格式化字符串 83 //日志记录期间的输出。 84 func (h Hash) TerminalString() string { 85 return fmt.Sprintf("%x…%x", h[:3], h[29:]) 86 } 87 88 //字符串实现Stringer接口,当 89 //完全登录到文件中。 90 func (h Hash) String() string { 91 return h.Hex() 92 } 93 94 //FORMAT实现fmt.formatter,强制字节片按原样格式化, 95 // 96 func (h Hash) Format(s fmt.State, c rune) { 97 fmt.Fprintf(s, "%"+string(c), h[:]) 98 } 99 100 //unmarshaltext以十六进制语法分析哈希。 101 func (h *Hash) UnmarshalText(input []byte) error { 102 return hexutil.UnmarshalFixedText("Hash", input, h[:]) 103 } 104 105 //unmarshaljson以十六进制语法解析哈希。 106 func (h *Hash) UnmarshalJSON(input []byte) error { 107 return hexutil.UnmarshalFixedJSON(hashT, input, h[:]) 108 } 109 110 //marshalText返回h的十六进制表示形式。 111 func (h Hash) MarshalText() ([]byte, error) { 112 return hexutil.Bytes(h[:]).MarshalText() 113 } 114 115 //setbytes将哈希值设置为b。 116 //如果b大于len(h),b将从左侧裁剪。 117 func (h *Hash) SetBytes(b []byte) { 118 if len(b) > len(h) { 119 b = b[len(b)-HashLength:] 120 } 121 122 copy(h[HashLength-len(b):], b) 123 } 124 125 //生成工具测试/quick.generator。 126 func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { 127 m := rand.Intn(len(h)) 128 for i := len(h) - 1; i > m; i-- { 129 h[i] = byte(rand.Uint32()) 130 } 131 return reflect.ValueOf(h) 132 } 133 134 //scan实现数据库/sql的scanner。 135 func (h *Hash) Scan(src interface{}) error { 136 srcB, ok := src.([]byte) 137 if !ok { 138 return fmt.Errorf("can't scan %T into Hash", src) 139 } 140 if len(srcB) != HashLength { 141 return fmt.Errorf("can't scan []byte of len %d into Hash, want %d", len(srcB), HashLength) 142 } 143 copy(h[:], srcB) 144 return nil 145 } 146 147 //值实现数据库/SQL的值器。 148 func (h Hash) Value() (driver.Value, error) { 149 return h[:], nil 150 } 151 152 //UnprefixedHash允许封送不带0x前缀的哈希。 153 type UnprefixedHash Hash 154 155 //unmashaltext从十六进制解码散列。0x前缀是可选的。 156 func (h *UnprefixedHash) UnmarshalText(input []byte) error { 157 return hexutil.UnmarshalFixedUnprefixedText("UnprefixedHash", input, h[:]) 158 } 159 160 // 161 func (h UnprefixedHash) MarshalText() ([]byte, error) { 162 return []byte(hex.EncodeToString(h[:])), nil 163 } 164 165 /////////地址 166 167 //地址表示以太坊帐户的20字节地址。 168 type Address [AddressLength]byte 169 170 //BytesToAddress返回值为B的地址。 171 //如果b大于len(h),b将从左侧裁剪。 172 func BytesToAddress(b []byte) Address { 173 var a Address 174 a.SetBytes(b) 175 return a 176 } 177 178 //BigToAddress返回字节值为B的地址。 179 //如果b大于len(h),b将从左侧裁剪。 180 func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) } 181 182 //hextoAddress返回字节值为s的地址。 183 //如果s大于len(h),s将从左侧剪切。 184 func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) } 185 186 //ishexaddress验证字符串是否可以表示有效的十六进制编码 187 //以太坊地址。 188 func IsHexAddress(s string) bool { 189 if hasHexPrefix(s) { 190 s = s[2:] 191 } 192 return len(s) == 2*AddressLength && isHex(s) 193 } 194 195 //字节获取基础地址的字符串表示形式。 196 func (a Address) Bytes() []byte { return a[:] } 197 198 //big将地址转换为大整数。 199 func (a Address) Big() *big.Int { return new(big.Int).SetBytes(a[:]) } 200 201 //哈希通过左填充零将地址转换为哈希。 202 func (a Address) Hash() Hash { return BytesToHash(a[:]) } 203 204 //十六进制返回地址的符合EIP55的十六进制字符串表示形式。 205 func (a Address) Hex() string { 206 unchecksummed := hex.EncodeToString(a[:]) 207 sha := sha3.NewKeccak256() 208 sha.Write([]byte(unchecksummed)) 209 hash := sha.Sum(nil) 210 211 result := []byte(unchecksummed) 212 for i := 0; i < len(result); i++ { 213 hashByte := hash[i/2] 214 if i%2 == 0 { 215 hashByte = hashByte >> 4 216 } else { 217 hashByte &= 0xf 218 } 219 if result[i] > '9' && hashByte > 7 { 220 result[i] -= 32 221 } 222 } 223 return "0x" + string(result) 224 } 225 226 //字符串实现fmt.stringer。 227 func (a Address) String() string { 228 return a.Hex() 229 } 230 231 //FORMAT实现fmt.formatter,强制字节片按原样格式化, 232 //不需要通过用于日志记录的Stringer接口。 233 func (a Address) Format(s fmt.State, c rune) { 234 fmt.Fprintf(s, "%"+string(c), a[:]) 235 } 236 237 //setbytes将地址设置为b的值。 238 //如果b大于len(a),就会恐慌。 239 func (a *Address) SetBytes(b []byte) { 240 if len(b) > len(a) { 241 b = b[len(b)-AddressLength:] 242 } 243 copy(a[AddressLength-len(b):], b) 244 } 245 246 //MarshalText返回的十六进制表示形式。 247 func (a Address) MarshalText() ([]byte, error) { 248 return hexutil.Bytes(a[:]).MarshalText() 249 } 250 251 //unmarshaltext以十六进制语法分析哈希。 252 func (a *Address) UnmarshalText(input []byte) error { 253 return hexutil.UnmarshalFixedText("Address", input, a[:]) 254 } 255 256 //unmarshaljson以十六进制语法解析哈希。 257 func (a *Address) UnmarshalJSON(input []byte) error { 258 return hexutil.UnmarshalFixedJSON(addressT, input, a[:]) 259 } 260 261 //scan实现数据库/sql的scanner。 262 func (a *Address) Scan(src interface{}) error { 263 srcB, ok := src.([]byte) 264 if !ok { 265 return fmt.Errorf("can't scan %T into Address", src) 266 } 267 if len(srcB) != AddressLength { 268 return fmt.Errorf("can't scan []byte of len %d into Address, want %d", len(srcB), AddressLength) 269 } 270 copy(a[:], srcB) 271 return nil 272 } 273 274 //值实现数据库/SQL的值器。 275 func (a Address) Value() (driver.Value, error) { 276 return a[:], nil 277 } 278 279 //UnprefixedAddress允许封送不带0x前缀的地址。 280 type UnprefixedAddress Address 281 282 //unmashaltext从十六进制解码地址。0x前缀是可选的。 283 func (a *UnprefixedAddress) UnmarshalText(input []byte) error { 284 return hexutil.UnmarshalFixedUnprefixedText("UnprefixedAddress", input, a[:]) 285 } 286 287 //MarshalText将地址编码为十六进制。 288 func (a UnprefixedAddress) MarshalText() ([]byte, error) { 289 return []byte(hex.EncodeToString(a[:])), nil 290 } 291 292 //mixedcaseaddress保留原始字符串,该字符串可以是也可以不是 293 //正确校验和 294 type MixedcaseAddress struct { 295 addr Address 296 original string 297 } 298 299 //NewMixedCaseAddress构造函数(主要用于测试) 300 func NewMixedcaseAddress(addr Address) MixedcaseAddress { 301 return MixedcaseAddress{addr: addr, original: addr.Hex()} 302 } 303 304 //newMixedCaseAddressFromString主要用于单元测试 305 func NewMixedcaseAddressFromString(hexaddr string) (*MixedcaseAddress, error) { 306 if !IsHexAddress(hexaddr) { 307 return nil, fmt.Errorf("Invalid address") 308 } 309 a := FromHex(hexaddr) 310 return &MixedcaseAddress{addr: BytesToAddress(a), original: hexaddr}, nil 311 } 312 313 //unmashaljson解析mixedcaseaddress 314 func (ma *MixedcaseAddress) UnmarshalJSON(input []byte) error { 315 if err := hexutil.UnmarshalFixedJSON(addressT, input, ma.addr[:]); err != nil { 316 return err 317 } 318 return json.Unmarshal(input, &ma.original) 319 } 320 321 //marshaljson封送原始值 322 func (ma *MixedcaseAddress) MarshalJSON() ([]byte, error) { 323 if strings.HasPrefix(ma.original, "0x") || strings.HasPrefix(ma.original, "0X") { 324 return json.Marshal(fmt.Sprintf("0x%s", ma.original[2:])) 325 } 326 return json.Marshal(fmt.Sprintf("0x%s", ma.original)) 327 } 328 329 //地址返回地址 330 func (ma *MixedcaseAddress) Address() Address { 331 return ma.addr 332 } 333 334 // 335 func (ma *MixedcaseAddress) String() string { 336 if ma.ValidChecksum() { 337 return fmt.Sprintf("%s [chksum ok]", ma.original) 338 } 339 return fmt.Sprintf("%s [chksum INVALID]", ma.original) 340 } 341 342 //如果地址具有有效校验和,则valid checksum返回true 343 func (ma *MixedcaseAddress) ValidChecksum() bool { 344 return ma.original == ma.addr.Hex() 345 } 346 347 //original返回混合大小写输入字符串 348 func (ma *MixedcaseAddress) Original() string { 349 return ma.original 350 }