Ethereum Wire Protocol
https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol
ÐΞVp2p Wire Protocol
https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol
https://github.com/ethereum/devp2p/blob/master/rlpx.md
RLPx specification
https://github.com/ethereum/devp2p/blob/master/rlpx.md
RLP
https://github.com/ethereum/wiki/wiki/[%E4%B8%AD%E6%96%87]-RLP
RLP coding principle
在想为什么要用RLP编码?RLP通过首字节快速判断一串编码的类型,可以利用RLP存储一个树状结构,类似json这种结构。
Why do you want to use RLP coding? RLP through the first byte quickly determine a string of coding types, you can use RLP to store a tree structure, similar to json this structure.
#coding=utf8
def rlp_encode(input):
if isinstance(input,str):
if len(input) == 1 and chr(input) < 128: return input
else: return encode_length(len(input),128) + input
elif isinstance(input,list):
output = ''
for item in input: output += rlp_encode(item)
return encode_length(len(output),192) + output
def encode_length(L,offset):
if L < 56:
return chr(L + offset)
elif L < 256**8:
BL = to_binary(L)
return chr(len(BL) + offset + 55) + BL
else:
raise Exception("input too long")
def to_binary(x):
return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256)
strData = "dog"
listData = ["cat", "dog"]
strRlp = rlp_encode(listData)
print(repr(strRlp))
Secp256k1
https://en.bitcoin.it/wiki/Secp256k1
#coding=utf8
from secp256k1 import PrivateKey
k = PrivateKey(None)
f = open("priv_key", 'w')
f.write(k.serialize())
f.close()
keccak-256 sha3
https://ethereum.stackexchange.com/questions/550/which-cryptographic-hash-function-does-ethereum-use
Connecting to the network
https://github.com/ethereum/go-ethereum/wiki/Connecting-to-the-network
ÐΞVp2p节点通过发送使用RLPx(一种加密和认证的传输协议)的消息进行通讯。
The Vp2p node communicates by sending a message using RLPx, an encrypted and authenticated transport protocol.
RLPx协议默认通过30303端口发送数据包。
The RLPx protocol sends packets by port 30303 by default.
ÐΞVp2p协议两种不同模式:使用TCP的主协议和使用UDP的发现协议
ÐΞVp2p protocol two different modes: the primary protocol using TCP and the discovery protocol using UDP
发现协议通过DHT(Distributed Hash Table)找到对等端,连接到引导节点的特定服务器,接收一个对等端的小清单。一旦有了这些对等端,连接它们,它们又会共享它们的对等端,再连接这些对等端,按此方法直到拥有网络中所有对等端的完整清单。
The discovery protocol finds the peer through the DHT (Distributed Hash Table), connects to a specific server on the boot node, and receives a small list of peers. Once these peers are available, connect them, share their peers again, connect to the peers, and follow this method until they have a complete list of all the peers in the network.
enode格式(encode format)
public_key_hex@ip_address:30303?discport=30301
TCP listening port : 30303
UDP discovery port : 30301
example:
enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301
var MainnetBootnodes = []string{
// Ethereum Foundation Go Bootnodes
"enode://[..pub_key..]@52.16.188.185:30303", // IE
"enode://[..pub_key..]@13.93.211.84:30303", // US-WEST
"enode://[..pub_key..]@191.235.84.50:30303", // BR
"enode://[..pub_key..]@13.75.154.138:30303", // AU
"enode://[..pub_key..]@52.74.57.123:30303", // SG
// Ethereum Foundation Cpp Bootnodes
"enode://[..pub_key..]@5.1.83.226:30303", // DE
}
Discovery nodes
来源需要在已知节点记录中,不在则会被丢弃。
The source node needs to be recorded in the known node, otherwise it will be discarded.
成为已知节点,必须ping引导节点,当引导节点接收到ping,会先响应一个pong,然后再发一个ping,并等待对方响应一个pong回去。引导节点收到pong响应才会将nodeID加入到已知节点列表中。
Become a known node, you must ping the boot node, when the boot node receives the ping, will first respond to a pong, and then send a ping, and wait for the other party to respond to a pong back. The boot node receives the pong response to join the nodeID to the list of known nodes.
***************************************
老鱼,从事互联网技术十余年,知名上市公司CTO;炒股十余年,从亏损几十万到略有盈利;顺应创业大潮多次创业,在传统行业和手游行业有所获;研习佛学易理,性格淡泊清净!
欢迎有兴趣的朋友加入微信群和电报群,一起学习探讨,一起实现咱们的小目标!