最近,一位之前一直在寻找它的用户在边肖向我们提出了一个问题。相信这也是很多币圈朋友经常疑惑的问题:以太坊的源代码开发和程序开发相关问题。带着这个问题,让专业的边肖告诉你为什么。
RLP(递归长度前缀),中文翻译过来叫递归长度前缀编码,是以太坊序列化采用的编码方式。RLP主要用于以太坊中数据的网络传输和持久存储。
对象序列化的方法有很多,比如JSON编码,但是JSON有一个明显的缺点:编码结果很大。例如,它具有以下结构:
序列化变量S的结果是{"名称":"ictlecoder","性":"男性"},字符串长度为35,实际有效数据为ictlecoder和Male,共16个字节。我们可以看到JSON的序列化引入了过多的冗余信息。假设以太坊采用JSON序列化,原来50GB的区块链现在可能需要100GB,但没那么简单。
所以以太坊需要设计一个结果更小的编码方法。
RLP编码的定义只处理两种类型的数据:一种是字符串(比如字节数组),一种是列表。字符串是指二进制数据的字符串,列表是嵌套的递归结构。,它可以包含字符串和列表,例如[";猫",[";小狗","奶牛"],"马",[],"猪",[";],"绵羊"]是一个复杂的列表。其他类型的数据需要转换成以上两类。转换的规则不是由RLP编码定义的,而是可以根据你自己的规则进行转换。比如struct可以转换成list,int可以转换成binary(属于字符串的范畴),以太坊里的整数是以大终端的形式存储的。
从RLP编码的名字就可以看出它的特点:一是递归,编码的数据是递归结构,编码算法也是递归处理;第二个是长度前缀,即RLP编码有一个前缀,这个前缀与编码数据的长度有关。这可以从下面的编码规则看出来。对于取值在[0,127]之间的单字节,其编码为自身。
例1:A的代码是97。
如果字节数组长度l=55,编码的结果是数组本身,加上128l作为前缀。
例2:空字符串的编码是128,即128=1280。
例3:3的结果:abc编码为131979899。,其中131=128len(";abc")和979899依次是ABC。
如果数组长度大于55,第一个编码结果是183加上数组长度的编码长度,然后是数组长度本身的编码。最后是字节数组的编码。
请多阅读关于上述规则的文章,尤其是数组长度的编码长度。
示例4:编写以下字符串:
Thelengthofthissentenceismorethan55bytes,andIknowitisbecauseIdesigned
inadvance.这个字符串一共86个字节,86的编码只需要一个字节,就是它本身。因此,编码结果如下:
184868410410132108101110103116104321161041051153211510111011611099101321051153211410132116104971103253
前三个字节计算如下:
184=1831,因为数组长度86编码后只占一个字节。
86是86
的数组长度84是t
的代码例5:对一个重复1024次的字符串进行编码,结果是:18540979797979797979797。
1024根据bigendian编码为0040,省略了前导零,长度为2,所以185=1832。
规则1~3定义了字节数组的编码方案,下面介绍list的编码规则。。在此之前,我们将列表长度定义为子列表的编码长度之和。
如果列表长度小于55,则编码结果的第一位是192加上列表长度的编码长度,然后依次连接子列表的编码。
注意,规则4本身是递归定义的。例6:[";ABC","def"]是200131979899131100101102。
abc的代码是131979899,DEF的代码是131100101102。编码后两个子串的总长度为8,因此编码结果的第一位计算为:192^8=200。如果列表长度超过55,则编码结果的第一位是247加上列表长度的编码长度,接着是列表长度本身的编码,最后依次连接子列表的代码。
规则5本身是递归定义的,类似于规则3。
Example7:
["Thissentenceismorethan55byteslong,""IknowitisbecauseIdesigneditinadvance"]
的编码结果为
。248881798410410132108101110103116104321111023211610410511532115101110116101110991013210511532109111114101321161049711032535332981211161011154432163733210711011111932105116329810199971171151013273321121141014510010111510510311010110032105116
前两个字节的计算方法如下:
248=2471
88=862。在规则3的例子中,长度是86。在本例中,因为有两个子字符串,,每个子串本身的长度占1个字节,所以总共占2个字节。
根据规则2,第三个字节179是179=12851
。第55个字节163也得163=12835
例8:最后,让';让我们看一个稍微复杂一点的例子来加深我们对递归长度前缀
的理解。["abc"["Thelengthofthissentenceismorethan55bytes,""IknowbecauseIdesigneditinadvance"]]
编码结果为:
24894131979899248881798410410132108101110103116104321111023211610410511532115101110116101110991013210511532109111114101321161049711032535332981211161011154432163733210711011111932105116329810199971171151013273321121141014510010111510510311010110032105116
根据规则2,列表中的第一个字符串abc的编码结果为131979899,长度为4。
列表中的第二项也是列表项:
["Thissentenceismorethan55byteslong,""Iknowit'sbecauseIdesigneditinadvance"]
根据规则5,结果是
248881798410410132108101110103116104321111023211610410511532115115115116101110991013210511532109
的长度为90。所以整个列表的编码结果第二位是90^4=94,占用1个字节,第一位是247^1=248
。以上五项都是RPL的编码规则。
实现RLP编码时,每种语言都需要将对象映射成两种形式:字节数组或列表。以go语言编码struct为例,它将被映射到一个列表中。例如,对象Student被视为列表[";actatlecoder","男性"]
[XY001]如果地图类型是编码的,可以采用下面的列表形式: 。[[";"],[";"],[";"]
解码时,首先根据编码结果第一个字节f的大小,判断如下规则:
1。如果f[0,128],那么它本身就是一个字节。
2。若f[128,184],则为长度不超过55的字节数组,数组长度为l=f-128
。3。如果f[184,192],那么它就是一个长度大于55的数组,长度本身的编码长度是ll=f-183,然后从第二个字节开始读取长度为ll的字节,按照BigEndian编码成整数L。l是数组的长度。
4。若f(192,247),则是编码后总长度不超过55的列表,列表长度为l=f-192。递归使用规则1~4进行解码。
5。如果f(247,256),那么它是一个编码长度大于55的列表,其长度本身的编码长度为ll=f-247,然后从第二个字节开始读取长度为ll的字节,按照BigEndian编码成整数L。l是子列表的长度。然后根据解码规则递归解码。
以上解释了什么是递归长度前缀编码,名字本身就很好的解释了编码规则。
(1)以太坊源学习-—RLP编码()
(2)RLP编码原理的简单分析
()
节点发现功能主要涉及服务器表udp等几种数据结构,它们都有自己的事件响应周期。节点发现功能由他们合作完成。其中,每个以太坊客户端启动后都会在本地运行一个服务器,网络拓扑中的相邻节点被视为节点,Table是节点的容器。Udp负责维护底层连接。下面重点介绍事件循环处理的重要字段和关键部分。
私钥该节点的私钥,用于与其他节点建立连接时的握手协商
协议所有支持的上层协议
静态节点默认静态对等体。当节点启动时,它们将首先发起连接以建立邻居关系
。新传输较低的传输层实现,它定义了握手过程中的数据加密和解密方法。默认的传输层实现是用newRLPX()创建的rlpx,这不是本文
的重点。ntab典型的实现是Table,所有的peer都以nodes的形式存储在Table
ourhandshake中与其他节点建立连接时的握手信息。,包含本地节点的版本号和支持的上层协议
addpeer——连接握手完成后,连接进程通过此通道通知服务器
监听周期。,启动底层监听套接字,收到连接请求时,接受后调用setupConn()启动连接建立过程
服务器的主要事件处理和功能实现循环
。节点唯一表示网络上的一个节点
IP-IP地址
UDP/TCP-UDP/TCP端口号用于连接
。ID在以太网中唯一标识的节点,本质上是一个椭圆曲线公钥,对应于服务器的私钥。节点的IP地址不一定是固定的,但是ID是唯一的。
[XY001]SHA-用于计算节点间的距离表主要用于管理与本节点和其他节点
的连接的建立、更新和删除。桶-所有对等体根据它们与该节点距离被放置在不同的桶中。详见节点维护
刷新请求-更新表请求通道
。Table的主事件循环主要负责控制刷新和重新验证过程。
refresh.c以固定间隔(30秒)启动对等刷新进程的计时器
refreshreq接收其他线程向表提交的刷新对等连接的通知,收到通知后开始更新。有关详细信息,请参见稍后更新邻居关系
。重新验证。c-定期重新检查连接节点有效性的计时器。具体请参考下面的探针检测
udp负责节点间通信的底层消息控制。,也就是表运行的Kademlia协议的底层组件
conn——底层监听端口
的连接。addpending-UDP用于接收挂起的通道。使用场景是,当我们向其他节点发送数据包时,我们可能希望收到它的回复。,pending用来记录这个还没有到达的回复。例如,当我们发送ping数据包时,我们总是希望对方回复pong数据包。此时,您可以构造一个挂起的结构。,它包含预期的pong包和相应的回调函数的信息,并将该丁鹏传递给udp的该通道。Udp在收到匹配的pong后执行预设的回调。
gotreplyUDP用于接收来自其他节点的回复。有了上面的addpending,在收到回复后,遍历已有的pending链表,看看是否有匹配的pending。
服务器中的Table和ntab是Table
udp的同一个处理周期,负责控制消息的向上提交和收发,控制
udp的底层接受包周期。,其负责从其他节点接收分组
。以太坊使用Kademlia分布式路由存储协议来维护网络拓扑。建议先阅读并理解分布式协议。更权威的信息可以在维基上找到。。一般来说,协议:
源代码以表结构保存所有桶,桶结构如下:
节点在条目和替换中可以相互转化。如果Validate失败,entries节点将被替换数组中原来的节点替换。
有效性检测是使用ping消息来探测活动。。Table.loop()启动定时器(0~10s),定时随机选择一个桶,向其条目中的最后一个节点发送ping消息。如果对方响应pong,则探测成功。
Table.loop()会定期(定时器到期)或不定期(收到refreshReq)更新邻居关系(发现新邻居),两者都调用doRefresh()方法。这种方法对于在网络上找到几个离自己最近的节点和三个随机节点很有用。
表格';slookup()方法用于查找目标节点,其实现是Kademlia协议,通过节点间的中继。一步一步,接近目标。
当节点启动时,它将首先启动与已配置静态节点的连接。发起连接的过程称为拨号,这个过程通过在源代码
中创建dialTask来跟踪。dialtask是指服务器启动时,任务
一次性发起与其他节点的连接。,调用newDialState()根据预先配置的StaticNodes初始化一批dialTask,这些任务在Server.run()方法中启动。
拨号进程需要知道目的节点(dest)的IP地址。如果你不';如果不知道,您必须首先使用recolve()来解析目的地的IP地址。如何化解??就是先用Kademlia协议在网络中找到目标节点。
当获得目标节点的IP后,下一步就是建立连接,就是通过dialTask.dial()
建立连接。连接建立的握手过程分为两个阶段。第一阶段是在SetupConn()中实现
时的ECDH密钥建立,第二阶段是协议握手和相互交换支持的上层协议
。如果两次握手都通过,dialTask会将对方的信息发送到服务器的addpeer通道
。
以太坊是一种区块链的实现。在以太网中,许多节点相互连接,构成了以太网。以太网节点软件提供两个核心功能:数据存储和契约代码执行。在每个以太坊节点中,存储了完整的区块链数据。以太坊不仅在链上存储交易数据。编译后的合同代码也保存在链上。在以太坊的整个节点中,还提供了一个虚拟机来执行契约代码。以太坊虚拟机以太坊区块链不仅存储数据和代码每个节点还包含一个虚拟机(EVM)来执行契约代码——,这听起来像一个计算机操作系统。实际上这是以太坊区别于比特币的核心点:虚拟机的存在让区块链进入2.0时代,也让区块链第一次成为应用开发者的友好平台。以上内容来自:以太坊DApp发展入门教程
如何运行以太坊源代码go-以太坊
安装基于MIPS的linux头文件
$CD$prjroot/kernel
$tar-xjvflinux-2.6.38.tar.bz2
$CDLinux-2.6.38
在指定路径下创建一个包含文件夹,用于存储相关头文件。
$mkdir-p$target_prefix/include
ensuresthatthesourcecodeofLinuxoperatingsystemisclean,sothatmrproper
cangeneratetherequiredheaderfile
.$makeARCH=MIPSheaders_check
$makeARCH=MIPSINSTALL_HDR_PATH=destheaders_INSTALL
将目标文件夹中的所有文件复制到指定的包含文件夹。
$CP-RVdest/include/*$TARGET_PREFIX/include
Finally,deletethefolder
$RM-RFdest
$LS-L$target_prefix/include
ofthesoftwareplatformforbuildingenvironmentandHVACsystemsimulation.ETH是以太坊的数字令牌,开发者需要向ETH付费来支持应用的运行。以太币和其他数字货币一样,可以在交易平台上买卖。
通俗点说。以太坊是一个开源的数字货币平台和区块链平台,它为开发者提供了建立在区块链之上的平台.
相信通过以太坊源代码开发和以太坊程序开发的介绍,您对以太坊源代码开发有了更透彻的了解,感谢您的支持和关注!