待字閨中開(kāi)發(fā)了一門區(qū)塊鏈方面的課程:《深入淺出ETH原理與智能合約開(kāi)發(fā)》片排,馬良老師講授朵诫。此簡(jiǎn)書(shū)文集記錄我的學(xué)習(xí)筆記辛友。
課程共8節(jié)課。其中剪返,前四課講ETH原理废累,后四課講智能合約邓梅。
第二課分為三部分:
- 以太坊交易
- MPT與RLP
- MPT與RLP實(shí)驗(yàn)
這篇文章是第二課第三部分的學(xué)習(xí)筆記:MPT與RLP實(shí)驗(yàn)。
這節(jié)課是上機(jī)實(shí)驗(yàn)九默,檢驗(yàn)前一小節(jié)課程內(nèi)容震放。
1、課前準(zhǔn)備
1.1 拉取代碼
新建一個(gè)工作目錄驼修,比如 WorkDir 殿遂,執(zhí)行如下命令,下載老師的教學(xué)代碼乙各。
git clone https://git.coding.net/blockchainsaw/mastering_eth_course.git
進(jìn)入到第2課的目錄下墨礁,進(jìn)入到 trie 目錄。
1.2 安裝依賴
老師已經(jīng)將要安裝的依賴寫(xiě)成了文件耳峦。cat setup.sh
可查看具體有哪些恩静。直接執(zhí)行即可,source setup.sh
蹲坷。
執(zhí)行 source setup.sh 過(guò)程中驶乾,提示沒(méi)有 pip ,搜索了一下怎么安裝的循签。
安裝方法:sudo apt-get install python-pip
查看pip版本:pip -v
查看pip幫助:pip -help
1.3 安裝vim
老師執(zhí)行 vim rlptest.py
查看代碼级乐,我照做,提示沒(méi)有安裝 vim 县匠,又去搜索怎么安裝风科。安裝方法sudo apt install vim
,安裝成功后乞旦,可以查看代碼了贼穆。
Vim 是一個(gè)很厲害的編輯器。簡(jiǎn)單學(xué)習(xí)了幾個(gè)入門級(jí)的命令兰粉,比如:從光標(biāo)后插入 a
故痊、 從光標(biāo)前插入 i
、退出編輯模式 Esc
玖姑、保存修改退出vim回到終端 :wq
崖蜜、不保存修改退出vim回到終端 :q!
客峭、等豫领。
1.4 使用tmux
了解到老師在課程中使用了 tmux 終端,比Ubuntu默認(rèn)的好用舔琅,也安裝了一下等恐。sudo apt-get install tmux
學(xué)習(xí)幾個(gè)常用的操作:
左右分屏:Ctrl+B
,%
(按Ctrl+B,再按shift+5)
上下分屏:Ctrl+B
课蔬,"
退出分屏:Ctrl+B
囱稽,X
或者exit
切換分屏:Ctrl+B
,→
或者Ctrl+B
二跋,←
退出tmux:Ctrl+B
战惊,&
接下來(lái)就是查看代碼,執(zhí)行代碼扎即,檢驗(yàn)前面所學(xué)內(nèi)容了吞获。
2、RLP編碼演示
進(jìn)入到 lessson_2/trie 目錄谚鄙,執(zhí)行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'))
輸出結(jié)果如下:
以下是6個(gè)例子文字版及結(jié)果分析闷营,編碼規(guī)則可參考前一小節(jié)《MPT與RLP》的最后一部分——5烤黍、RLP的編碼標(biāo)準(zhǔn)。
- 字符串傻盟,長(zhǎng)度為10速蕊,即十六進(jìn)制的0xa。0x80+0xa=0x8a娘赴。所以編碼的前綴為0x8a规哲,后面的68、65筝闹、6c、6c腥光、6f关顷、77、6f武福、72议双、6c、64分別為helloworld的10個(gè)字母捉片。
original string :helloworld
original string length: 0xa
after encode : 0x8a68656c6c6f776f726c64
- 單一字節(jié)平痰,如果其值介于[0x00, 0x7F]之間,則保持不變伍纫。
original string :
original string length: 0x1
after encode : 0x00
- 單一字節(jié)宗雇,如果其值介于[0x00, 0x7F]之間,則保持不變莹规。
original string :~
original string length: 0x1
after encode : 0x7e
- 字符串赔蒲,長(zhǎng)度為0x57,長(zhǎng)度的長(zhǎng)度為1,0xb7+0x1=0xb8舞虱,所以前綴是0xb857欢际。接下來(lái)的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
- 再貼一下規(guī)則。
本例中椅寺,分別按字符串編碼規(guī)則對(duì)兩個(gè)元素編碼浑槽,兩個(gè)的長(zhǎng)度都小于55。
對(duì)第一個(gè):0x80+0x2c=0xac
編碼為:
ac5065746572205069706572207069636b65642061207065636b206f66207069636b6c65642070657070657273
對(duì)第二個(gè):0x80+0x1f=0x9f
編碼為:
9f426574747920426f7474657220626f7567687420736f6d6520627574746572
而這兩個(gè)編碼的總長(zhǎng)度為0x4d配并,長(zhǎng)度的長(zhǎng)度為1括荡,0xf7+0x1=0xf8,所以前綴是0xf84d溉旋,后面再接上前面得出的兩個(gè)編碼畸冲,即為最終的編碼結(jié)果。
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
- 空字符串观腊,規(guī)定為0x80
original string :
original string length: 0x0
after encode : 0x80
- 另外邑闲,我又照著第5個(gè)改寫(xiě)了一個(gè)例子。
原始為["PPeter Piper picked a peck of pickled peppers,Betty Botter bought some butter"]梧油,總長(zhǎng)度為0x4d苫耸,列表中只有一個(gè)元素。
對(duì)這一個(gè)元素編碼為0xb84d……(后面是字符串)±茉桑現(xiàn)在編碼的長(zhǎng)度不再是0x4d褪子,而是0x4f,因?yàn)槎?個(gè)長(zhǎng)度的前綴骗村。所以整個(gè)列表的前綴是0xf84f嫌褪。最終結(jié)果為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編碼演示
下面的例子中笼痛,只第一個(gè)放上完整代碼,其他的只寫(xiě)主要部分琅拌。編碼規(guī)則可參考前一小節(jié)《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')
主要關(guān)注部分為刻坊,key = 0x010102, value = 'hello' 。
執(zhí)行python exercises/ex1.py
党晋,得出結(jié)果紧唱。
編碼分析:key之前補(bǔ)一個(gè)四元組活尊,(倒數(shù))第0位區(qū)分奇偶信息,偶數(shù)為0漏益;第1位區(qū)分節(jié)點(diǎn)類型蛹锰,葉子節(jié)點(diǎn)1。0010=2绰疤,高4位為2铜犬,key的長(zhǎng)度為偶數(shù),再補(bǔ)一個(gè)四元組0x0轻庆,即前綴為0x20癣猾,最終的Hex-Prefix編碼為0x20010102,如圖最后一行余爆。
3.2 例子ex2.py
(010102: 'hellothere')
這個(gè)例子同前一個(gè)纷宇,只是value值不同。最終的Hex-Prefix編碼也是0x20010102蛾方。
接下來(lái)3個(gè)例子可參考下圖像捶。ex2b.py這個(gè)例子的MPT圖可能不對(duì),待請(qǐng)教老師后再做補(bǔ)充桩砰。
3.3 例子ex2b.py
(010102: 'hello')
(010103: 'hellothere')
前綴:key之前補(bǔ)一個(gè)四元組拓春,(倒數(shù))第0位區(qū)分奇偶信息,奇數(shù)為1亚隅;第1位區(qū)分節(jié)點(diǎn)類型硼莽,擴(kuò)展節(jié)點(diǎn)0。0001=1煮纵,高4位為1懂鸵,key的長(zhǎng)度為奇數(shù),不需要再補(bǔ)一個(gè)四元組0x0行疏,所以前綴為0x1 匆光。
3.4 例子ex2c.py
(010102: 'hello')
(0101: 'hellothere')
擴(kuò)展節(jié)點(diǎn)的前綴:key之前補(bǔ)一個(gè)四元組,(倒數(shù))第0位區(qū)分奇偶信息隘擎,偶數(shù)為0殴穴;第1位區(qū)分節(jié)點(diǎn)類型凉夯,擴(kuò)展節(jié)點(diǎn)0货葬。0000=0,高4位為0劲够,key的長(zhǎng)度為偶數(shù)震桶,再補(bǔ)一個(gè)四元組0x0,所以前綴為0x00 征绎。
擴(kuò)展節(jié)點(diǎn)的前綴:key之前補(bǔ)一個(gè)四元組蹲姐,(倒數(shù))第0位區(qū)分奇偶信息磨取,奇數(shù)數(shù)為1;第1位區(qū)分節(jié)點(diǎn)類型柴墩,葉子節(jié)點(diǎn)1忙厌。0011=3,高4位為3江咳,key的長(zhǎng)度為奇數(shù)逢净,不需要再補(bǔ)一個(gè)四元組0x0,所以前綴為0x3 歼指。
3.5 例子ex2d.py
(010102: 'hello')
(01010255: 'hellothere')
此例子的前綴同前一個(gè)例子爹土。另見(jiàn)上圖。
后記:寫(xiě)這篇筆記時(shí)學(xué)會(huì)了怎么在簡(jiǎn)書(shū)高亮代碼踩身,就是用鍵盤上1左邊那個(gè)鍵把代碼包起來(lái)胀茵,前后各一個(gè),或者一段文字的前面各三個(gè)挟阻。畫(huà)風(fēng)有點(diǎn)不好看~
不足之處請(qǐng)指教琼娘,謝謝。