00:00
在我们以太坊的黄皮书里面,其实不光是前面的这一部分内容,是整个以太坊白皮书的一个具体的实现,一个具体的应用,而且大家还可以看到就是它后边的这一个附录。很多内容很多,而且就是里边其实理论性的东西,大家其实想要知道的东西,在里边都可以找到,都可以找到答案,比如说啊,当然这第一个,这主要是名词解释了啊,附录A附录。B、大家可以看到,这就是RLP。就是应该叫呃递归长度前缀对吧,这样一种编码方式,大家如果感兴趣的话就可以看一看,当然这个即使是中文版的黄黄皮书也没有把这个翻译过来,所以大家只能读这个英文啊。呃,他这个讲的还是很详细的,把这个都讲下来了,然后C的话就是呃,Hpcoding编码方式,Perhaps prex pas前缀的编码方式,其实就是跟我们今天讲的这些东西是是一样的啊,就是说怎么样把这个nes去去做一个编码。
01:18
然后附录D的话,那就是modified。MPT,我们的梅克尔的一下数,这就是这个基本的数据结构,在这里边也都可以找到它的这些证明和定义啊,非常详细。呃,这里还有这个叫pre的contract,就是小预编译合约。这里是这样的一个概念。大家可以看到这个附录里面也是非常的复杂啊,这都是数学公式啊,数学推导。
02:03
啊,我想找下一个附件都找不到了,呃,大家看这这里是这个签名交易,这里专门他把这个拿出来去去说就是怎么样用这个公司要自己去做这样的签名。啊,这是一些这个关于费用的一些一些安排或者计划,对吧。所以大家可以看到就是后面的内容非常非常多,呃,大家看这个这个滚动条。到这里,这个附录下面还还很多内容的,对吧?这个真的是比正文还要多,所以呃,大家如果想要对底层有更多的了解,完全可以去看啊,呃,当然了,如果大家要是说对这部分本来也不是太感兴趣,也不想了解太多底层,那大家就可以这个。好好做一点准备,然后下周开始我们就真正开始做项目了。
03:05
呃,如果还有一些同学是发现这个就是区块链这边开发,觉得好像本身区块链这块都比较比较费劲,之后可能如果要找工作什么的,也有可能就就去,就觉得这个区块链可能也不好找工作的话,那大家也可以去储备一些,就是呃,像这个外部方面的技能啊,前端后端之前大家也都前端讲的很细,对吧,然后后端也也用go去实现过这个web后端,所以这些我觉得所有的技能大家都可以综合起来。因为呃,在我的理解里边,就是区块链本身怎么说呢,大家学区块链其实不是要简单的学区块链这个东西,其实更多的可能是学一种综合的。综合的能力,对吧,把所学的所有东西糅合在一起,然后产生新的想法,产生新的这种。
04:03
运用的这种能力,这个可能是更关键的东西,呃,就包括大家发现上的课可能也是大家什么东西都学。前端后端go,然后比特币以太坊,然后之后还有这个超级账本可能还会,呃,是不是还有其他老师要给大家再讲一讲别的东西,这个我还不太确定啊,呃,就是大家可能会发现,就是为什么会讲这么多。就好像看起来很杂,看起来很很乱的东西呢,其实我觉得就是因为区块链本来就是一个大杂烩。里边大家如果要是说这会儿给大家开始开始去讲一些网络上上的知识,我觉得其实也用得着对吧。呃,你说区块链里边完全用不到网络吧,其实也是不可能的,特别是如果要是想要去做底层链开发的话,你如果不懂网络,那几乎是不可能的事情。嗯,那如果说大家。
05:01
这个兴趣点在数据库,那其实区块链完全也可以把数据库这一部分给大家讲的很详细,对吧,因为本身底层就是一个分布式的数据库吗?呃,用到的是level DB对吧,Google这开源的DB,那那这个如果要展开讲的话,那又是很庞大的一门课。所以其实。那那大家在平常这个应用的过程当中,那就更不要说前端后端什么样的技术都要用,所以在这个过程当中,我觉得。可能就是。大家会接触到很多很多东西,那自己去选取自己想要,就是真正感兴趣,真正想要的东西,这肯定是可以的,但我更建议大家就是有一个,有一个柔柔和,有一个综合,把自己学到的东西能够融会贯通起来。当然这个也是看大家各自的各自的状况啊,有些同学可能就是,呃,之前对本身对这个前后端开发都已经很熟了,那现在可能一柔和就觉得就是得心应手。
06:06
有些同学如果要是之前很多东西都没做过,都没见过的话。可能就需要就是待在。可能就需要自己该在更专注的去把精力放在某一方面,可能大家去多学一点前端,或者多做一点这个外部开发,我觉得也是可以的啊。大家像。今天晚上,明天大家休息的话,也可以就是自己整理整理,总结总结,因为接下来我们做项目的话,呃,就是也没有很多理论。而且项目里边,可能特别是我们这个以太坊这一部分的项目是它的综合性还是挺强的,我觉得还是挺强的,因为会涉及到很多可能大家完全没用过的。框架也好,还是工具也好,呃,就是就是像咱们这个第一个项目,可能首先会给大家介绍这这么一个框架。然后之后呢,项目里边可能会去用到这个mongo DB,可能最后一个项目会用到react,会用到next JS,可能还会用到一些UUI方面的一些开发的一些组件,对吧,Material UI,所以就是牵扯到的东西可能会很多,但是我觉得。
07:19
呃,就是我们不要对这个觉得就比较排斥对吧,一想诶,这么多东西我怎么能学的会,其实大家看从开始学区块链到现在大家已经学了很多东西了,呃,包括这个底层链的技术,比特币这一部分,分布式的一些基础内容,包括以太坊这边本身东西也很多,对吧。Solid web3以太坊的基础,所以呃,我觉得大家到现在为止,其实已经可以有一些综合性的这样能力去更多的做一些自己想做的事情了,如果要是有些同学觉得自己的基础不够的话,那就可以更加专注的,比方说那我干脆像今天我说这么多这个。
08:05
就是这么,呃,底层理论化的一些东西,那大家觉得不感兴趣,那大家就可以去。去多了解一些,如果说我以后我也那个可能找这个区块链工作,我觉得也也也不太合适,可能我也不想拿这些概念去跟人面试,那那大家就可以去自己多看一看外部开发呀,或者怎么样,我觉得这个也是挺不错的一个方式啊。好了,我们还是言归正传,说这个黄皮书吧。扯了扯别的也没看着大家更精神啊,所以所以我们还是继续看黄皮书,大家如果要是觉得累的话,这个我觉得也没关系啊,该睡睡开玩笑,我还是觉得应该打起精神来,就是呃,多多去去摄入一点知识也是好的嘛,好,我们之前在这个黄皮树里边,我们应该是讲到了。
09:08
子账户这个地方对吧,所以接下来我们要讲的这部分内容就是交易了,那交易呢,在以太坊里边,那大家看到它的定义是一个单一的加密学签名的指令,其实也就是说他用密码学去做这个数字签名,然后呢,它是发出来的一个指令,他认为这是一个指令,那其实这是对EVM,或者说对以太坊系统而言的。当我们发起一个交易的时候,以太坊它就会接收到一个指令,就是我要开始做状态转移了,从一个状态要迁移到另一个状态,所以说从这个角度看的话,交易它是一个指令,当然我们从另外一个角度看的话,交易它是一个加密的数据包嘛,呃,这就是不同角度的看法,通常它是由以太坊系统外的操作者创建,那也就是说通常都是因为外部账户发起的交易,我们假设外部操作者是人的话,呃,那软件工具就是用于构建和散播,这个其实就是说所谓就是我们如果要是呃这个。
10:18
如果是大家用程序去做这件事情的话,那其实就就已经不是这种真正意义上的人去创建的外部账户了,对吧,所以这就相当于是去散播的一个状态了。这个。然后他把这里的交易分成两种类型,一种是消息调用,那其实这里所说的消息调用就是我们平常所说的交易,给大家发起一个交易,他这里把这个消息和交易也会稍微的混一些,他经常会说消息就是交易,交易就是一种消息。另一种呢,那就是通过代码创建新的账户,也就是所谓的合约创建。就是两类最重要的交易,一种就是普通交易,朝另外一个账户去转账或者发送数据。
11:04
表现为消息调用。另外一种就是创建合约。两种交易共同的字段,那这个大家都很熟了啊,Non GA price gas limit,然后to value,还有VRS,这是签名相关的一些数据。此外,合约的创建。他还要包含以下四个,这个可能我们之前没有专门说过,就是创建合约的时候,我们发起的那个交易,它还有一个什么东西呢。它其实是没有to这个参数,因为我们知道它是发送到零账户的,对吧,零地址的,所以它会没有我们普通的这个to,但是会有一个in的字段。它是一个不限制大小的字节数组,也就是一个变长的数据字呃字节数组,它用来指定的是账户初始化程序的U代码。
12:00
所以说。呃,这一段就是in的这一个字段,相当于就指定了。告诉EVM我是要去创建一个合约,然后还告诉了EVM,我应该怎么样去做初始化,怎么样去创建我的这个合约啊,这就是以你的这个东西。In呢,它是EVM的代码片段了,它返回一个body,这是一个。账户每次接收到消息调用的时候都会执行的代码,也就是说我们发布一段字解码原始的代码给到EVM,然后它会生成我们整个这个合约能够运行的那个代码。所以说我们给他发的是初始化的代码,它生成的是真正之后我们能用的代码。就是这样一个过程。而因为的代码,它是只有在合约创建的时候执行一次,然后就没用了。我们真正的合约的代码。我们记得它是在。
13:03
作为一个呃,就是字节以字节码的形式是放在data里面传过去的,对吧,所以说那个是会永久保保存的,而这里带着的这个阴影的字段,它是只有创建的时候调用一次。好,另外接下来就说了一个消息调用的交易,那它就不是了,那它有什么呢?有data。Data是一个不限制大小的字节数组,用来指定消息调用的输入数据啊,在这个里面它去描述的时候就是in,这个字段是T,是transaction,是交易,那data就是TD。好,我们接下来看一下他的这个表达吧,哇,这是又又这么一串啊,大家看一下。大家看这是什么意思啊,首先我们先看一下上面它定义的这个TT是什么东西,TT是to。就是我们合约发送给谁这个字段大家可以看啊。
14:03
哦呃,前面我说错了,就是在这个创建合约的时候,也是有发送给谁的,那我们知道它是发送给零地址嘛,所以它也会包含在里面,那这个时候它其实是会去判断,就是这里是说我们整个的这个。交易的状态转换这样一个函数对吧,他要去做对应的这一个存储的时候,KV的存储的时候,它去怎么样去存储呢?它对应的内容是前面定义的所有的这些东西合在一起。就是我们定义的NUS from to,呃,不是from吧,就是GA price GA limit to,还有value,还有我们签名的这个VRS,呃,另外就是还有一的data,所有的这个这些东西合在一起去构建我们交易存储的对象。那如果说TT是空的话,也就是说发送到的。
15:05
是零地址对吧。TT是to嘛,所以它如果是空的话,我们发送的是零地值,所以上面的这一行给定的就有一个ti,就有一个阴的字段。那这个表示的就是是一个。合约的创建交易。那下面这一行otherwise,那就否则对吧,否则的话它给定的就是TD,就给定我们的调用的data pilo。好,所以呃,接下来它还有一个解释啊,就是所有变量都是作为整数来进行RP编码的,这是一个假设啊。呃,接下来这就是他分别属于什么类型,我们可以看到像这个NUS,还有它这个签名,呃签名的这个VRS这几个参数,其实全部包括GA price和GA limit,全部都是N256,也就是小于二的256次的一个整数。
16:06
啊,这是这里的一个定义。那大大家可以看到这里还有一个TWTW是单独的那个签名里边的那个V。就是V是TW。因为它是R和S,大家知道是签名里边的前后两个字段,对吧,那V呢,它是比较小的一个带校验性质的一个一个字段,所以这一部分它比较小。N5就可以了,就是二到五次以下对吧,就是32。呃,另外就是这个ti这是一个字节,属于属于字节,TD也是属于字节对吧。好,那么这里又重新定义了一下N啊,这个我们就不用说了。呃,然后这里还有一个就是说地址哈希,就是说这个我们的to的这个地址,他在哈西的时候呢。
17:01
啊,这里定义了一个,它是一个20字,20字节的地址,哈希值所,或者当创建合约的时候是RLP,空字节取例。所以大家注意看,就是这就是说如果创建合约的时候,图的是零地址的话,那它是把一个空字节做了RLP编码。会给到这个,呃,提土这个字字段。就是这样的一个状况啊。好,接下来我们再看一下区块。区块这一部分的话,在以太坊里边区块的组成成分是哪几部分呢?大家可以看到啊,主要是区块头。Block block header,还有就是组成区块的交易T,那就是一组T对吧,一组交易。和一些其他一些血块头U。所以这就是我们的书块了,对吧,书块的头也是在区块的,也是区块的一部分,所以大家可以看到区块其实是分成这么三部分来组成的。
18:08
那区块头毫无疑问是这里面最重要也是最复杂的一个东西了,对吧。里面包含什么样的东西呢?负区块的哈希。然后书块的哈西啊oos就是uncle啊omer就是应该也是叔叔的意思,所以OS Hu就是当前区块的书块列表的哈系。下面还有一个东西叫做benefit谁呃,这这怎么拼我都不知道了啊,大家应该能够想象得到,就是说谁能得到好处对吧?应该就是be那个词转过来的应该是beneficiary吧,Beneficiary对吧?它代表什么呢?它代表是成功的挖到这个区块所得到的。交易费的接收地址。
19:00
所以也就是说在这个区块区块头里面,它是要包含这个信息的,交易费给到谁。然后就是我们所说的三棵MPT树,它的树根,状态树树根,交易树树根,还有收据树树根。之后还有一个log log就是日志的不同过滤器,那这个是方便我们之后再去检索整个日志,然后去做信息筛选用的。啊,另外还有一个很重要的东西叫做difficulty。Difficulty表示的是当前区块的难度水平。它可以根据前一个区块的难度水平和时间戳计算得到,用HD表示。那这个difficulty到底怎么算呢?等一下我们先把这块说完,等一下专门给大家讲一下这个difficulty,就这个,至少我们还能实际去算一算,然后去校验一下。我觉得可能或许。大家稍微能觉得有点意思啊,我们把这个讲一讲。
20:03
呃,然后那当然就是这个number number,这就是这个区块高度,这就不要说了,Gas limit gas used的这个上限,区块的上限和当前用掉的所有盖的总和,Time step就是时间戳,X data就是我们在出块的时候添加的任意的额外的数据,最后呢,Mix hash和NUS是用来做工作量证明的两个字段,对吧?他们两个结合起来就能够证明真正的完成了这个pow的验证,好,那么在这里边大家就可以看到。呃,他他最后还给了这么一个一个定义啊,就是说一个区块,它是什么东西呢?它就是区块头BH对吧,H heather。还有区块里面的交易传达神,还有区块的书块构成,这才叫东西构成。好,我们在这里,就是我们先看一下这个源码吧。
21:04
大家猜这个整个区块,这个架构应该在哪里放?还,还记得我们之前这个账户是在哪里找到的吗?Car对吧,对,这个也是在car里面,基本的数据,数据结构定义全在块里面。哦,这个又是很慢啊,稍微等一下。这个这么办啊。好,我先去打开一个PPT,准备跟大跟大家说一下这个难度这个话题吧。但是这个话题是难度调整,这个可能又稍微深一点了,这边还没有打开啊,大家知道以太坊是可以做难度调整的,对吧,那以太坊的难度是什么时候调整一次。
22:04
对啊,我我记得好像上次跟他说过对吧,以太坊的难度是每个块都会重新调整一次,每个块都会重新计算一次,所以以太坊的这个难度调整是非常的灵活,非常的就是迅速的响应是非常迅速的,这个跟比特币不一样,好我们进到这个,靠这个文件夹下面,我们看到在下边诶没有找到呢。诶,我们看到了block.go对吧?呃,这个不对啊,肯定不是blocks.go。我先把它退出来吧。哦,他怎么这么卡。应该直接点这个T啊。我还是开一下热点来,直接连一下好了,这个确实很成问题啊。
23:16
哦,这个这个真的进不去啊,大家可以就是能进去的话,大家可以自己看一下,就是在types下面会有对应的区块和transaction的一个定义,大家可以进去自己看一下啊。好,那么嗯,怎么了。好,那么我们还是就是,呃,我觉得这个难度调整是不是我们还是得讲到这个后边黄皮书里面相关的内容的时候,才可以去去详细的看这个难度调整啊。呃。大家觉得现在对难度调整有一个概念吗?没有概念是吧,好,那我们再往这个黄皮书后面再看一看,黄皮书的后边,它会提到这个好,就在后面一点,好那么我们继续先往后看啊,刚才我们是讲到了这个区块,区块头这些里边的东西,接下来呢,就是交易收据。
24:20
那我们前面提到区块头里边有三个梅,呃,煤克尔,梅克尔帕特里下树的数根,其中有一个是交收据收据数对吧?那么什么是交易收据呢?那它其实是为了能使交易信息对这个零知识证明啊,索引搜索有用,其实简单说就是我们把一些冗仪的信息拿出来之后,方便大家重新去搜,重新去查询,对吧,重新去做一些简单的验证,离职证明这样的东西,呃,这样的东西我们单独提出来,就把它作为一个交易收据这样的数据类型存储起来。那么每个交易执行的过程当中都有一些特定的信息,就会做一些编码,然后就会存成交易收据,那我们看一下这个交易收据它是一个什么样的东西啊?交易收据是一个包含四个条目的元素,也就是说它包含什么东西呢?一个是。
25:19
交当呃,就是包含交易收据的区块,也就是他进的这个块儿里边。当前的这个交易发生之后累积的gas使用量。啊,就是到他这里。到这个交易发生之后累积起来的GA,然后还有一个是交易的过程当中创建出来的日志合集。这也是跟交易相关的,对吧,跟日志相关的东西,还有是由这些日志所构成的布隆过滤器。所以大家可以看到,呃,就是最后还有一个是交易的状态代码,那这个状态代码其实后面大家可以看到,就是其实不存的,之前有一个地方也也讲到这个这个状态代码之后。
26:05
就是到目前为止,已经是不再去存在整个这个交易的数据里面了,就收据的数据里面了,所以现在大家可以看到,呃,整个这个交易收据它转换成RLP编码的序列化字节数组的时候,到底是一个什么样的状态呢?它会把前面提到的RU,也就是说。在这个交易当中累积起来的GA。还有创建出来的日志的合集。还有。相对应的布隆过滤器放在一起作为一个整体,然后进行RLP的序列化。啊,这就是这个它存储的时候是以这种方式去去做存储的。呃,那大家可以看到啊,这就是另外前面的这一部分,它的这个状态交易,原先要的这个状态交易是什么呢?是交易前的状态跟state route,那现在就把这个改了,就直接改成这个零了,对吧,所以这个就是现在直接把它移除掉了,相当于。
27:14
那下边这里的要求呢,就是会要求这个状态代码是一个整数,他们的这些规范数据,数据类型的定义。呃,然后这个盖的使用量也必须是一个正整数,然后布隆过滤器是一个2048位数据的哈希。然后它就相当于是哈希成了一个256位字节,256个字节这样一个败数组。那最后还有一个这个RL呢,它是一个日志项,这个日志项就包含一系列日志,就是O0O11个日志项,它是记,记录了日志产生者地址,还有日志主题,还有一些字节数据所构成的这样的一个元素,所以大家还记得吗?我们之前给大家看过那个交易。
28:09
他记录下来的那个日志对吧,它里面首先有一个dress。就是谁发起的这个交易,然后进行的这个日志记录,对吧?呃,然后后边会有一系列的主题topics。Topics是我们在定义事件的时候,可以用index关键字去定义,在solid里面,对吧?定义了index的话就相当于创建的索引,那么这就相当于有一个主题,我们可以根据这个主题进行去进行筛选。那这些主题就会保存在这里所谓的这个OT里面。那剩下的其他的一些日志,我们没有见index的东西,那触发的事件所有的东西都包含在这个data里面,就是OD里面。所以大家就可以看到整个的这一个日志,像它包含的就是OA地址,还有一系列的topic,还有整个的OD3样东西。
29:07
那当然了,地址它当然是一个20字节的这样的一个字符字符串对吧。呃,那那后面这个还有还有要求就是任意的T属于这个OT,任意一个topic。任意一个主题,那么他得要求这个主题要属于这个三二。啊,这是另外一个要求啊。还有这个OD,那那这个它要求它是属于bad。这里当然就是还定义了布隆过滤器函数M,它可以把一个日志项精简成一个256字解哈希,所以这个是在做什么呢?他就是在说之前这个。布隆过滤器RB,它就是一个二百二零四八位数据的一个哈希,对吧,所以它其实就是在说怎么样算这个哈希。我们怎么算呢?就把它整个的这个就是M32048这个布隆过滤器。
30:07
大家看这个,这是一个什么样的布隆过滤器呢?它通过设置。2048位里边的三位数值来给给定一个随机的字节序列,所以它是这样的一个很奇怪的一个过滤器啊,这是一个特特别的过滤器。那么用它在这个大家可以看到所有的T,如果要是属于。OA和这个OT里边的这个并集,然后呢,用后边的这个不能过滤器去对它进行过滤。然后得到的这一个可开可CA256哈希第一位的11位数据就可以实现,呃,得到它的这个256字节的写啊,但是这个就比较绕口啊,其实我也对这个东西整个的过程并不是特别的熟,大家其实看一看就可以了啊。
31:02
接下来这一部分大家可能需要了解,就是整体有效性。我们怎么样确认一个区块是有效的呢?就是说我们怎么样拿到一个区块之后,确认它是一个合法的区块,可以把它接收进来呢?那下面就定义了一组这样的限制条件。那首先大家可以看到啊,就是说呃,HRHR是什么。已经忘记了头里面的东西,对吧,Head里边的东西R呢,应该是一个是不是一个某一个root是不是。这里好像没写。如果没记错的话,应该是state root啊。就是就是我们的状态数的树根。所以就是在你的。头里边写到的这个状态数的数根,它应该等于什么呢?等于这个整个这个区块里边所有的状态转换合起来之后归集到状态数据。
32:13
归集到的那个根节点应该得到的跟区块里面记录的这个跟状态跟是一样的,对吧,所以这就是你你把里边的交易一个一个去执行一遍,归结起来的那个状态数的数根就应该是跟我现在的状态是一样的。那hoo应该是。O应该是输块是不是对,O应该是输块哈希对吧?那书块哈希就必须要等于我当前的块里边,它输块做序列化之后的哈希值。所以这也是肯定必须要满足的,对吧。然后htt应该是transaction route对吧。这是我们的交易数,那交易数那就等于你必须要把里边的每一笔交易,然后一个一个构建起来,构建成我们的一个维克尔帕特一下数,然后对应的那个根节点必须要等于这个HT,对吧?
33:13
这又一步校验,然后he的话E是。这个真是一下子想不起来啊。哦,这就是reception的这个root。就是我们的收据数,那收据数应该等于什么呢?应该等于整个我的这个区块里边所有的收据。然后把它们两两结合,算出它的这个哈希对吧,等于我现在这个收据数的数根,最后还有一个HB。HB是什么?HB是布隆过滤器对吧,HB是布隆布隆过滤器。就必须要等于我们前面定义好的这个,你把这样的一组这个topic,还有这个地址传进去之后,根据我们定义的这个M32048的过滤器算出来的那个哈希,一定要等于这里边给定的那个布隆过滤器的那个ho,对吧,AB。
34:16
所以这么五条验证规则,这就能保证我们这一个取款是合法的。好,这个这么说起来确实是比较比较枯燥,我们最好还是看一下这个啊,我这里好像刚才这个还没有打开啊,我们这源码看起来是看不了了。哎呀,这个好吧,那呃,刚话音未落。结果还是不行,算了好,那么其实大家可以想象到在这个代码里面它会怎么样去实现,其实肯定就是各种各样的那种校验条件,对吧,各种各样的if else,如果要是它不等于的话,那就直接报错。
35:04
只有等于我们这个校验过程才能通过,所以大家可以到时候到源码里面去看一看它怎么去实现。
我来说两句