github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/p2p/enr/entries.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 //版权所有2017 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 enr 26 27 import ( 28 "crypto/ecdsa" 29 "fmt" 30 "io" 31 "net" 32 33 "github.com/ethereum/go-ethereum/crypto" 34 "github.com/ethereum/go-ethereum/rlp" 35 ) 36 37 //条目由已知的节点记录条目类型实现。 38 // 39 //要定义要包含在节点记录中的新条目, 40 //创建满足此接口的Go类型。类型应该 41 //如果需要对值进行额外检查,还可以实现rlp.decoder。 42 type Entry interface { 43 ENRKey() string 44 } 45 46 type generic struct { 47 key string 48 value interface{} 49 } 50 51 func (g generic) ENRKey() string { return g.key } 52 53 func (g generic) EncodeRLP(w io.Writer) error { 54 return rlp.Encode(w, g.value) 55 } 56 57 func (g *generic) DecodeRLP(s *rlp.Stream) error { 58 return s.Decode(g.value) 59 } 60 61 //WithEntry用键名包装任何值。它可用于设置和加载任意值 62 //在记录中。值v必须由rlp支持。要在加载时使用WithEntry,值 63 //必须是指针。 64 func WithEntry(k string, v interface{}) Entry { 65 return &generic{key: k, value: v} 66 } 67 68 //tcp是“tcp”密钥,它保存节点的tcp端口。 69 type TCP uint16 70 71 func (v TCP) ENRKey() string { return "tcp" } 72 73 //udp是“udp”密钥,它保存节点的udp端口。 74 type UDP uint16 75 76 func (v UDP) ENRKey() string { return "udp" } 77 78 //ID是“ID”键,它保存标识方案的名称。 79 type ID string 80 81 const IDv4 = ID("v4") //默认标识方案 82 83 func (v ID) ENRKey() string { return "id" } 84 85 //IP是“IP”密钥,它保存节点的IP地址。 86 type IP net.IP 87 88 func (v IP) ENRKey() string { return "ip" } 89 90 //encoderlp实现rlp.encoder。 91 func (v IP) EncodeRLP(w io.Writer) error { 92 if ip4 := net.IP(v).To4(); ip4 != nil { 93 return rlp.Encode(w, ip4) 94 } 95 return rlp.Encode(w, net.IP(v)) 96 } 97 98 //decoderlp实现rlp.decoder。 99 func (v *IP) DecodeRLP(s *rlp.Stream) error { 100 if err := s.Decode((*net.IP)(v)); err != nil { 101 return err 102 } 103 if len(*v) != 4 && len(*v) != 16 { 104 return fmt.Errorf("invalid IP address, want 4 or 16 bytes: %v", *v) 105 } 106 return nil 107 } 108 109 //secp256k1是保存公钥的“secp256k1”密钥。 110 type Secp256k1 ecdsa.PublicKey 111 112 func (v Secp256k1) ENRKey() string { return "secp256k1" } 113 114 //encoderlp实现rlp.encoder。 115 func (v Secp256k1) EncodeRLP(w io.Writer) error { 116 return rlp.Encode(w, crypto.CompressPubkey((*ecdsa.PublicKey)(&v))) 117 } 118 119 //decoderlp实现rlp.decoder。 120 func (v *Secp256k1) DecodeRLP(s *rlp.Stream) error { 121 buf, err := s.Bytes() 122 if err != nil { 123 return err 124 } 125 pk, err := crypto.DecompressPubkey(buf) 126 if err != nil { 127 return err 128 } 129 *v = (Secp256k1)(*pk) 130 return nil 131 } 132 133 //keyError是一个与键相关的错误。 134 type KeyError struct { 135 Key string 136 Err error 137 } 138 139 //错误实现错误。 140 func (err *KeyError) Error() string { 141 if err.Err == errNotFound { 142 return fmt.Sprintf("missing ENR key %q", err.Key) 143 } 144 return fmt.Sprintf("ENR key %q: %v", err.Key, err.Err) 145 } 146 147 //IsNotFound报告给定的错误是否意味着键/值对 148 //记录中缺少。 149 func IsNotFound(err error) bool { 150 kerr, ok := err.(*KeyError) 151 return ok && kerr.Err == errNotFound 152 }