007:MPT与RLP实验|《ETH原理与智能合约开发》笔记

待字闺中开发了一门区块链方面的课程:《深入浅出ETH原理与智能合约开发》,马良老师讲授。此简书文集记录我的学习笔记。

课程共8节课。其中,前四课讲ETH原理,后四课讲智能合约。
第二课分为三部分:

  1. 以太坊交易
  2. MPT与RLP
  3. MPT与RLP实验

这篇文章是第二课第三部分的学习笔记:MPT与RLP实验。


这节课是上机实验,检验前一小节课程内容。

1、课前准备

1.1 拉取代码

新建一个工作目录,比如 WorkDir ,执行如下命令,下载老师的教学代码。

git clone https://git.coding.net/blockchainsaw/mastering_eth_course.git

进入到第2课的目录下,进入到 trie 目录。

1.2 安装依赖

老师已经将要安装的依赖写成了文件。cat setup.sh 可查看具体有哪些。直接执行即可,source setup.sh

执行 source setup.sh 过程中,提示没有 pip ,搜索了一下怎么安装的。
安装方法:sudo apt-get install python-pip
查看pip版本:pip -v
查看pip帮助:pip -help

1.3 安装vim

老师执行 vim rlptest.py 查看代码,我照做,提示没有安装 vim ,又去搜索怎么安装。安装方法sudo apt install vim,安装成功后,可以查看代码了。

Vim 是一个很厉害的编辑器。简单学习了几个入门级的命令,比如:从光标后插入 a 、 从光标前插入 i 、退出编辑模式 Esc 、保存修改退出vim回到终端 :wq 、不保存修改退出vim回到终端 :q! 、等。

1.4 使用tmux

了解到老师在课程中使用了 tmux 终端,比Ubuntu默认的好用,也安装了一下。sudo apt-get install tmux

学习几个常用的操作:
左右分屏:Ctrl+B%(按Ctrl+B,再按shift+5)
上下分屏:Ctrl+B"
退出分屏:Ctrl+BX 或者exit
切换分屏:Ctrl+B或者Ctrl+B
退出tmux:Ctrl+B&

接下来就是查看代码,执行代码,检验前面所学内容了。

2、RLP编码演示

进入到 lessson_2/trie 目录,执行python rlptest.py。其中,rlptest.py 的代码如下:

import sys
sys.path.append('src')
import rlp

test_list  = ["helloworld",
              chr(0),
              chr(126),
              "The quick brown fox jumps over the lazy dog The quick brown fox jumps over the lazy dog",
              ["Peter Piper picked a peck of pickled peppers","Betty Botter bought some butter"],
              '']  


for test in test_list:
    if isinstance(test, list):
        for s in test:
            print("original string in list :" + s)
            print("original string in list :" + hex(len(s)))
    else:
       print("original string :" + test)
       print("original string length: " + hex(len(test)))
    print("after encode : 0x" + rlp.encode(test).encode('hex'))

输出结果如下:

rlptest.py执行结果

以下是6个例子文字版及结果分析,编码规则可参考前一小节《MPT与RLP》的最后一部分——5、RLP的编码标准

  1. 字符串,长度为10,即十六进制的0xa。0x80+0xa=0x8a。所以编码的前缀为0x8a,后面的68、65、6c、6c、6f、77、6f、72、6c、64分别为helloworld的10个字母。

original string :helloworld
original string length: 0xa
after encode : 0x8a68656c6c6f776f726c64

  1. 单一字节,如果其值介于[0x00, 0x7F]之间,则保持不变。

original string :
original string length: 0x1
after encode : 0x00

  1. 单一字节,如果其值介于[0x00, 0x7F]之间,则保持不变。

original string :~
original string length: 0x1
after encode : 0x7e

  1. 字符串,长度为0x57,长度的长度为1,0xb7+0x1=0xb8,所以前缀是0xb857。接下来的54是字母T,……,67是字母g 。

original string :The quick brown fox jumps over the lazy dog The quick brown fox jumps over the lazy dog
original string length: 0x57
after encode : 0xb85754686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f672054686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f67

  1. 再贴一下规则。
RLP之list

本例中,分别按字符串编码规则对两个元素编码,两个的长度都小于55。

对第一个:0x80+0x2c=0xac
编码为:
ac5065746572205069706572207069636b65642061207065636b206f66207069636b6c65642070657070657273

对第二个:0x80+0x1f=0x9f
编码为:
9f426574747920426f7474657220626f7567687420736f6d6520627574746572

而这两个编码的总长度为0x4d,长度的长度为1,0xf7+0x1=0xf8,所以前缀是0xf84d,后面再接上前面得出的两个编码,即为最终的编码结果。

original string in list :Peter Piper picked a peck of pickled peppers
original string in list :0x2c
original string in list :Betty Botter bought some butter
original string in list :0x1f
after encode : 0xf84dac5065746572205069706572207069636b65642061207065636b206f66207069636b6c656420706570706572739f426574747920426f7474657220626f7567687420736f6d6520627574746572

  1. 空字符串,规定为0x80

original string :
original string length: 0x0
after encode : 0x80

  1. 另外,我又照着第5个改写了一个例子。
    原始为["PPeter Piper picked a peck of pickled peppers,Betty Botter bought some butter"],总长度为0x4d,列表中只有一个元素。

对这一个元素编码为0xb84d……(后面是字符串)。现在编码的长度不再是0x4d,而是0x4f,因为多2个长度的前缀。所以整个列表的前缀是0xf84f。最终结果为0xf84fb84d……(后面是字符串)。

riginal string in list :PPeter Piper picked a peck of pickled peppers,Betty Botter bought some butter
original string in list :0x4d
after encode : 0xf84fb84d505065746572205069706572207069636b65642061207065636b206f66207069636b6c656420706570706572732c426574747920426f7474657220626f7567687420736f6d6520627574746572

3、MPT编码演示

下面的例子中,只第一个放上完整代码,其他的只写主要部分。编码规则可参考前一小节《MPT与RLP》第2、3、4部分

3.1 例子ex1.py

代码如下:

import sys
sys.path.append('src')
import trie, utils, rlp

#initialize trie
state = trie.Trie('triedb', trie.BLANK_ROOT)
state.update('\x01\x01\x02', rlp.encode(['hello']))
print 'root hash', state.root_hash.encode('hex')
k, v = state.root_node
print 'root node:', [k, v]
print 'hp encoded key, in hex:', k.encode('hex')

主要关注部分为,key = 0x010102, value = 'hello' 。

执行python exercises/ex1.py,得出结果。

ex1.py执行结果

编码分析:key之前补一个四元组,(倒数)第0位区分奇偶信息,偶数为0;第1位区分节点类型,叶子节点1。0010=2,高4位为2,key的长度为偶数,再补一个四元组0x0,即前缀为0x20,最终的Hex-Prefix编码为0x20010102,如图最后一行。

3.2 例子ex2.py

(010102: 'hellothere')

这个例子同前一个,只是value值不同。最终的Hex-Prefix编码也是0x20010102。

接下来3个例子可参考下图。ex2b.py这个例子的MPT图可能不对,待请教老师后再做补充。

后3个例子的MPT图

3.3 例子ex2b.py

(010102: 'hello')
(010103: 'hellothere')

前缀:key之前补一个四元组,(倒数)第0位区分奇偶信息,奇数为1;第1位区分节点类型,扩展节点0。0001=1,高4位为1,key的长度为奇数,不需要再补一个四元组0x0,所以前缀为0x1 。

3.4 例子ex2c.py

(010102: 'hello')
(0101: 'hellothere')

扩展节点的前缀:key之前补一个四元组,(倒数)第0位区分奇偶信息,偶数为0;第1位区分节点类型,扩展节点0。0000=0,高4位为0,key的长度为偶数,再补一个四元组0x0,所以前缀为0x00 。

扩展节点的前缀:key之前补一个四元组,(倒数)第0位区分奇偶信息,奇数数为1;第1位区分节点类型,叶子节点1。0011=3,高4位为3,key的长度为奇数,不需要再补一个四元组0x0,所以前缀为0x3 。

3.5 例子ex2d.py

(010102: 'hello')
(01010255: 'hellothere')

此例子的前缀同前一个例子。另见上图。


后记:写这篇笔记时学会了怎么在简书高亮代码,就是用键盘上1左边那个键把代码包起来,前后各一个,或者一段文字的前面各三个。画风有点不好看~

不足之处请指教,谢谢。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容