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  }