00:00
接下来这一部分是一个交易的详解,也就是说,呃,之前其实我们已经对这个交易已经接触过很多次了,然后我们平常的这个钱包的转账,我们在盖里边做的转账,呃,包括我们去发一个合约,发布一个合约,部署一个合约,我们去调用一个合约,其实我们用到的都是交易,我们都是发出交易去做这些事情的,那它到底是一个什么样的东西呢?我们先看一下交易的本质是什么,之前我们说它是一个就是调用的一个消息,或者它是一个签名的数据包,那在这里可能我们可以对交易有一些深层次的认识。比如说这里可以跟大家说,就是交易可以看成是外部拥有的账户,就是EOA所谓的普通账户发起的签名消息啊,当然这里是又把这个也也是不太好翻译啊,就是message嘛,也他确实是一段信息,大家对可能我把这个应该翻译成信息会比较好一点,就它是一段发起的一段签名信息。
01:07
所以也就是一段数据了,由以太坊的网络传输,最后它是会被序列化之后永久性的记录在以太坊区块链上,这是它的这个本质和一个生成传播和最终持久化的一个过程。而交易我们已经说了,呃,以太坊是一个状态机,它里边状态的改变就是靠交易,而且交易是唯一可以触发状态改变或者导致合约在E中执行的一个东西。只有交易能干这件事情,这就是所谓的transaction交易在整个以太坊系统当中的地位,呃,以太坊我们说它是一个就是世界计算机,它可以说是一个全局的状态机,但它是一个单立的状态机,所谓单利就是说它在一个一个时间段只是有一个就是大家,大家保留的只是它的一个状态,不可能有多个多个线程,这样的就是多个实例,这样的一个状态只是一个单实例的状态,而交易是唯一可以改变它状态的东西。这这又是重复一下上面的这个。
02:22
交易的这个地位啊,最后还有一个就是说合约,我们说智能合约,大家似乎一听到这个这个呃,智能两个字之后,可能就会有一种有一种感觉,就是说他应该是自己会会会玩儿起来的,自己可以处理很多事情的,但事实上不是啊,就是咱们现在生活当中,可能智能这个词就被滥用的比较多,就像我们说智能家居,其实大家如果用过的话,它其实也也也没太智能,可能就是很多东西还是得人去设置对吧,人去调整,所以。呃,智能合约,所谓智能合约并不是自己就能运行的,以太坊它的这个EVM的也不会就是所谓的在大家理解的,它是有一个这个就像相当于我们那个有一个守护进程,然后直接可以在后台跑起来,在后台运行的,不是这样的一个状态。
03:19
所有的这些东西,正常情况下可以认为它都是一个沉寂的一个状态,这都没有在运行。所有的以太坊上的一些变化都是起源于交易,只有交易才能唤醒他们的运行。所以这是交易的一个作用,呃提到这儿可以就是多插一个一个呃小八卦,就是前两天也是看到不知道大家关注不关注,比方说像像微神啊,或者像这有有一些这些很有名的开发人员,他们的一些呃社交网站或者怎么样,就前前些日子就看到微神就发了一条应该是推的消息,还是还是什么消息啊,就是说他就说很后悔。
04:05
把这个以太坊上的这个smart contract这个这个概念提出来,很后悔把这个东西叫做智能合约,他说呃,应该当时我取一个更加枯燥无味一些的名字,更加就是程序员化一点的一个名字,比如说呃,叫做复杂脚本,还是叫叫一个什么,就是我忘记他的那个原话了啊,就是说反正就是一个很听起来就没有那么高大上,听起来好像有点有点奇怪的一个东西,很很程序文化的一个东西,其实他的意思也就是说说是智能合约,但是事实上和智能其实不搭边。它可能看起来更像是一个自动化的脚本,所以呃,当然了,就是智能合约的这个命名,对于我们程序员来说可能没什么特别的,但是对于普通普通人来说,听到这个名字之后,他会很兴奋,所以说就是在这个商业上,产品上来说,他的这个命名真的是很成功的,也就导致这个以太网确实是很受欢迎,但是这会儿可能威神也是觉得好像这个有点。
05:18
因为这个不太切实的东西受到更广泛的关注,他觉得这个好像是不好的一件事情,呃,也导致了一些泡沫啊什么的,所以他他反而是有点儿后悔,说不敢把这个东西叫做智能合约啊,这就是一个,呃,一个小卦,大家也可以看得出来,就是可以加深一些大家对这个合约的这个印象,就它其实并不是说自己就就能自己执行的,就像所谓的人工智能一样,现在人工智能可能也没那么智能,对吧,他并不是说自己能干很多很多事情,而。以上的合约全部都是靠交易去出发执行的。
06:00
接下来我们再详细的看一下交易的数据结构,呃,这个比我们上节课提出来的那一个,呃,交易的里边包含的数据那就要详细很多了,这个就连它里面的那个,呃,本身以太坊实现的时候给定的名字也放出来了啊交易它是包含以下数据的一个序列化的二进制消息,也就是说二进制的一个信息吧,它包括哪些东西呢?一个叫做non。然后下面的东西我们都知道了,Announce,可能之前我们没怎么说啊,下面的我们都知道了,GA price,这就是一个交易发起的人,他要支付,他要消耗盖嘛,所以这个他要愿意为盖支付多少的单价呢?就是一个盖值多少以态呢,然后他会给定一个盖price的单位是尾,除了GA price之外呢,还有一个star GA,这就是大家平常设置的GA limit,就是你这一下最大愿意付多少GA量。
07:04
盖的数量上限是多少?To的话,那就是目的地址,我们要发,要发一笔交易,它的目的的以太坊地址是什么?Value是我们要发的以太数量,呃,有时候我们会发现这个value是零啊,我们很多的交易value都是零。呃,另外就是data data,这是一个可变长度的二进制数据负载,这个这个数据负载确实翻译过来好像总有点别扭,他英文可能还就是大家可能看起来好像还更好理解一些,就是它叫payload。说白了就是说这个东西是它包装成的一个对象,然后大家可以直观的理解,就是我们要传递去的数据。所有的都放在贝塔这个字段里面,最后还有就是VRS3个三个字段,这个他们都是签名的三个组成部分。就是我们椭圆曲线加密算法签名的三个组成部分。
08:00
呃,最后还有一个就是说交易消息的结构,它是用这个RLP编码方案进行序列化的,这就是我们所说的递归程度前缀的一个编码算法,它其实就是专门为以太坊里面设计的,就是它能够准准确和字节完美的呈现一个数据序列化的一个过程,这就是RP,别的概念基本上都没什么大不了的,对吧?但是大家看到就是有一个是前面好像我们没有特意提到,没有特意注意的,对,就是这个no。以太坊里边,为什么他专门要把这个NUS弄进来,放到交易里边去呢?前面咱们看那个,呃,盖里边自己发的两笔交易,其实看到了这个nu是个什么东西。对,大家还还记得我们前面发的一个交易,那个那次看到是是一,然后后面就是二就是三对吧,所以它其实就是一个地址发出来的交易的一个序列号,当时我们说可以理解成是个计数器一样的东西,所以它就是一二三一直顺序往上叠加的。
09:10
它的目的是什么呢?就是为了防止前面我们说到的消消息的重播,重重放攻击,但想想这个东西,为什么它就可以保证防止重放攻击?其实一开始我们提这个问题的时候,就就有同学已经说了,就是怎么样能防止重放攻击呢?我们让它唯一化,就是这个交易它有一个唯一性就可以了。那其实这个nu就是让它有了一个唯一性。他的意思就是说,如果我们想要发放一个交易的话,你必须给定一个唯一的序列号。而这个序列号必须是他怎么样才能校验通过呢?必须是你看他之前这个账号发出来的交易。从前往后一个一个排,是不是顺序排到这会儿刚好是这个序列号,如果是的话,它是合法的,如果不是。
10:05
那他就,呃不是说不合法,这就分情况了。比方说我们之前这个账号已经发了十笔交易,那他的序列号可能是从零到九。我们现在如果构建一个交易能给十的话。空去校验的时候一看啊,一查这个地址之前发出了十笔交易,从零到九,现在下一个档次就应该是十,我一看这个交易来了,让子也是十,好没问题,然后检查一下他的这个签名没问题,然后那个要转的这个数量都对,就是他的账户里面本来有这么多数量,好都过这些胶验之后,好我把它打包进进框,但如果说发现这个nu,本来下一个应该是十。他给的是九。那我就说已经有九了,你这个是一个无效的交易。这就保证了,如果说我们看到之前发送了一个浪19的一个交易,然后我直接把那个交易直接全盘复制一个过来,那如果再放出去的话,矿工去校验他通不过的地方,别的都能通过,因为你可以再来一单,你可以发同样多的以态,可以给同一个人发,那当然你的签名也可以是一样的,但是你的nu一定不一样。
11:21
所以是这一点会把它卡住,呃,当刚才我们是说了,如果说他这里那写九的话就会被拒绝,那如果他要是写11的话会怎么样呢。写11的话,他也会被拒绝。就是。矿工不会直接把他这个交易打到自己的这个包里边来,不会去给他出框,但是这笔交易他还是会放在交易池里边停留着。它会放在我们的,相当于是有一个缓冲池一样的东西,他会认为这是未来有可能会执行到的一笔交易。
12:00
所以他会等什么呢?等到我们网络当中又有了一个对,那是十的交易之后。有,有矿工再去挑交易的时候,发现这个纳斯是11的,就会认为这个是合法的了,所以嗯,就是这个过程大家就会看到,有时候你也可以随便指定一个很大的档,但是它一定是现在执行不了的,它一定不可能被确认镜块的它,但是它跟那个你指定一个很小的那种,就是肯定不会成立的交易又不同,它有可能在未来的某个时刻会被打包进金块。这就是NUS的一个作用啊,当然也可能会有时候会带来很多,呃,大家会觉得就是比较奇怪的一些地方,就是等一下我再跟大家分享一些东西啊,这这其实就是我们刚才说到这个浪的一部分,浪在黄皮书里面的定义,它是一个标量值,它等于从这个地址发送出来的交易数量,所以就是我们说的序号,你已经发出了九个的话,那就是当前的nu值,就是已经到了八,下一个就应该是九,就是就是这样的一个东西,或者说对于关联扣的账户,那其实呃,就是说是这个账户创建合约的数量。
13:22
创建合约也会记在这个NUS里面去。另外就是那不会明确存储作为区块链账账户状态的一部分,它是不会就是明确存进我们的账户状态的,账户的状态里面不包括这个,相反它是每一次要去校验的时候都去动态计算,所以就是说,呃,它并不是说就像我们的余额一样,直接写死在里边,它是一个值,我们直接读出来就可以用了,而是说每一次我们要校验交易的时候,你从头开始看吧。
14:00
他之前发布多少个交易,然后有多少笔交易,交易数量截止到目前为止,好它是多少,那应该是多少,是这样的一个过程。啊,这个可能会比大家一看这个就其实也是很麻烦的,对吧?呃,那这样的一个考量,设计的考量,其实还是为了安全性的考虑,因为这些东西你所有的东西它都可以伪造,如果你从一个状态当中直接去读取,而不做这个历史验证的话,肯定是有风险的。还有一个就是说,那是可以用于防止错误计算账户余额。因为我们知道,呃,有既然有这个账户余额的概念,我们平常做这个转账,账户状态改变就是一个减一个数,一个加一个数,而不像。比特币的u to,那样我们会把所有当前utxo状态都都提取出来,那个是其实是很安全很可靠的,而我们像这个只是改一个,改两个账户里面的数的话。
15:07
这个跟我们平常就是银行啊,或者我们后台服务器的做法没什么区别,对吧,就是个数而已,那万一这个出了错的,万一如果改错了呢?呃,所以就是说,呃,这些东西都是一种风险,那那子呢,他就可以强制来自任何交易,任何地址的交易按照顺序处理,这就防止说就像我们数据库里边一般处理交易的时候也都要加锁了,对吧,你不能说是我这边正在改这个,正在收一笔款的时候,我正在改这个数,你那边又来查查我的数就不对了吧,或者说两个人同时给我打款的时候,我这边最后只加了一次,这就有问题了,所以。他如果关联到这个账户上面去的话,那来计算他的这个按,就可以让他完全按照一定的顺序来执行,这能保证它这个交易的正确行,最后就是说使用档子可以确保节点计算有相同的余额和正确的序列交易等同于就是就是防止比特币这个冲放攻击的,其实所以它没有比特币utxo的这个设计的优势,它是考考虑的是保护了这个我们完整的账户系统,让我们大家更加容易更加方便的去应用这一套体系。
16:33
与此带来的是没有办法对抗重放攻击,那怎么办呢?所以就想出了弄死的这一招补救的方式,所以大家可以看到啊,就是呃,我们一直在说为什么比特币经典,为什么比特币经典,就是后来大家所有认为比特币不好的地方,或者说值得改进的地方都会发现,你要改它的话。改善了一个地方,然后就会带来另外一个地方的不足,就会带来就是你填了一个坑,发现给自己又挖了一个坑,你还得再去找别的地方去补,当然了,截止到目前为止,以太坊至少把这些可还是都补上,就是所有大家看到以太坊又多出来了很多很多设计,其实都是为了填填补这些问题,就包括我们之前讲的幽灵协议也好,包括我们讲的这个NUS其实也好,其实都是它跟比特币的不同都在这里。
17:27
嗯,好,所以这就是让大家大家深入的理解一下交易中NUS的这个作用,然后我们再多多提一句啊,就是说这个并发和nu这个关系,并发呢,大家都很熟悉这一个概念了,就说呃,比如说我们平常说的多线程多进对吧?呃,同时有很多个请求来,我们怎么样能同时响应,这个就是我们平常所说的并发的问题,以太坊本身它是一个允许操作并发的系统。
18:00
就是它有,它是一个分布式的网络,分布式的架构,它一定是允许并发的,呃,它有很多很多的节点,很多很多的客户端,呃,包括这个D什么的,那我们肯定不可能说,呃,大家一定要是按照一个顺序来,就是我在去访问这个节点的时候,你不能访问,或者说我访问这个节点的时候,你在美国都不能访问美国的节点,这肯定是不可能的,所以大家都可以同时访问,都可以同时处理大家的交易请求,从这个意义上说,这是并发的。但是从另外一个意义上来讲,它是强制执行单立状态,也就是说出块的时候只有一个系统状态,即使我们在中国,别人在美国同时提交交易,最后只能如果出现冲突的话,最后只能有一个正常的状态被大家确认到主链上。假如有冲突的话,那大家如果就是像刚才说的这个nu,如果本来我们都是同一个账户,现在nu应该是使我们全发nu为十的一个交易,那这个最后肯定只有一个能被确认,这是区块链的特点吧,对吧,就是我们肯定不允许出现冲突的这种状况,分叉状况出现,呃,那接下来就是说,假如说我们就是有多个独立的钱包或者是客户端,呃,我们现在至少大家其实已经有这样的东东西了,对吧,至少我们一个有一个mad ma还有一个GA。
19:34
我们如果想发一个交易给别人转账的话,目前至少这两种我们都是可以的,呃,当然了,Guess我们现在能做到的是只能在自己的测试网络或者自己的私链上去转账,因为如果想在测试网或者是主网上去转账的话,大家可能还得去同步它的区块,或者至少你得起一个清洁点,对吧?呃,要不然的话,你就还得去用这些远程的客户端,就像bus这些东西,但那个东西大家等到网络好的时候,大家时间比较闲的时候,让自己电脑跑着吧,同步几天,把它同步下来也是可以的啊,到时候自己就可以直接用自己的guess。
20:12
都不用任何的钱包工具,自己就可以,就是给别人转账啊,收钱啊,查询各种东西啊,自己的功能就全有了啊,那我们现在已经有这么多不同的客户端了,我们当然大家看到了地址是到处都可以用的,对吧?Mad mask里面的地址我们copy出来到GA里边也能用,我们在GA里面四店上给这个地址充进去的钱,到mama上一查,发现也有都有,呃,所以我们用这个相同的地址,假如说我们想要有同同时在这两个客户端或者钱包上面去生成交易。然后我们希望他们同时发送出来,假如说我们就有很多个交易想要去发的话。那这个时候怎么办呢?
21:02
但是咱们这这是很空的一个想法啊,呃,如果要是想具体的实例的话,那就不能想咱们平常转账的这个需求,比方说呃,我之前工作的时候,因为是区块链企业嘛,就是他自己也发自己,就是ICO之后要发自己的货币,对吧?呃,那肯定就有一个需求,就是说别人众筹的货币你得发放到人家的账户里面去,自己定义的这个货币得发放到别人的账户里面去。那这个时候我肯定就希望我我总不能是一个一个拿我的钱包去给别人转账吧,对吧,一下子ICO有可能几千个用户有可能对吧,几百个用户一笔一笔你手动去转这个,你就算你钱包这个很累了。那这个东西假如说我想要并发一下呢,我找一个人来帮忙,我找一个人,我说我这边有一个mama的钱包,你这边有一个盖客户端,好,我把我的账号也给你,咱们俩同时发币吧,同时给人发吧。
22:01
那这个时候。怎么办呢?这这这就是一个并发的场合,对吧,这个时候怎么办呢?怎么设置浪子呢,关键是。大家想如果要是正常的一个客户端的话,他设置na的规则是什么,咱们平常都没有,从来没有自己手动设对吧,都是他默认设好的,他设置的规则是什么。呃,他肯定就是先去查询之前的状态,如果之前已经是到了,已经有九个交易,现在该第该第十个了,那那应该为十,那他肯定下一次他发出来交易,他就给十,但这个时候咱们两个客户端都是这么干的,他都发现之前的交易是九。我现在应该给十,那那他们下一笔交易发出来,是不是都那都是十呢。所以这个时候同时发出来的交易就会有问题,注定他们两个之中只有一个生效。
23:02
那这个时候如果让我们来统一管理,我们想来协调这个机制的话,我们应该怎么样管理,让他们怎么样发呢?大家可以想象,这怎么样能保证他们能同时发。这个可能如果要是我们也没有处理过这样的情形,可能一下子也想不出来什么招是吧?呃,其实这个不光是想不出来什么招,其实大家可以看到我这里面已经列了两个,就下面列出来两种方案,但其实这两种方案大家仔细一看的话,呃,都不怎么地,可以说第一种方案是呃比较好讲,就是好想到的一种方案,就是说我自己另外设置一台服务器,或者说就是就是自己跑个程序吧,来处理这件事情,就是说我这个服务器干一件什么事情呢?我提供一个服务。我把我这边这边的这个ma ma mask和那边的那个GA客户端把他们管理起来,你们那边发交易不要自己直接就拿过去就发了,而是我把这边交易所有的交易给你们分配好。
24:17
你买你发这几个盖那边你发那几个,我为你们分别去分发交易,然后直接就给你们指定好。那所以说呃,那我的标准是什么呢?就是一般最好想想到的就是先来先服务你们两个客户端,谁那空闲了,谁先跟我说,哎,我这闲了,我可以发币了,那你就要给我提提个请求,然后我就给你分配一个交易过去,然后这个交易是我给你已经写好的not。谁先给我,我就给谁下一个这个过去,那另外一个你你后来一秒钟提到我这请求,那不好意思,刚才的那个是十,你这个就只能是11了,尽管有可能你发的还比他快,但是你这个只能是11,这是比较容易想到的一种方案,就是呃,至少是协调了这两个客户,客户端他们能让他们能工作了。
25:13
但是事实上大家想一下这个过程当中。其实是有可能出现所谓的单点故障,它单点故障是什么?就是我们相当于有一个中心化的东西在做这件事情,就是我们分配的这个服务器很重要,一旦他挂掉的话,那所有的东西都没用了。你分配的这些分配档次的机制也没有了,两边这个客户端和钱包也不知道该怎么干了。另外还有一个很大的问题,就是说我们分配档次的时候,是谁先来请求,我们就给谁分配,分配一个档次,按这个顺序,有可能先来的这个我给了他十号档,后面来这个我给了他11号。有可能11号那笔交易给的盖高,或者说本身那个是盖在,就是我们的那个客户端在发,他发的发送速度就快,而且跟周围的这个环境,网络环境也好,他发发发出去的也快,然后被打包的也快,就是按道理他是应该先先那个运行成功的,那这个时候,但是不行,他就得先等着十号。
26:24
路块才可以对吧,前面我们已经说过了,他必须按照这个顺序11号,他如果要跳中间隔一个的话,这是不允许被矿工打包的,所以在这种情况下,假如我们的时候他也不是慢,他直接就挂了。那怎么办呢?那那后面的11就再也上不去了,那不光11后面的十二十三后面所有的交易都上不去了,所以这个其实是大家看是有很大的问题的,后续的交易全部堵塞,所以这种方案比较容易想到,但是其实是也实现不了,呃,或者说就是实实现了之后也没有什么用,他的问题很大,呃,另外呢,我们想就做一个改进吧,能做一个怎么样的改进呢?
27:17
我们还是有一个统一的服务来做这件事情,怎么做呢?生成交易之后,这些交易我们先不给他分配到,而且这些交易也都不签名,就就是交易的原始数据,就把它放到同一个队列里面等待着,然后呢,我们另外起一个节点去跟踪。现在。就是我们现在。整个区块链上的交易,然后看现在的这个状态,那到哪了,这其实就是我们客户端其实都可以做的一件事情,对吧?当然ma MAS可能做不了这件事情,我们在里面是看不到的,呃,它自己本身是可以检测得到,但是我们没有这个接口,我们拿不到,呃,所以这个节点的作用呢,其实就是跟踪现在到底应该有到到哪个浪子。
28:09
然后到哪个na了,我们就从那个队列里边统一取出一个交易来,给他分配这个nu,然后签名交易。然后等他发到区块链当中之后。下一个交易,然后同样的动作,然后再拿下一个交易分配档次,分配档次的时候还是直接到区块链上去查的,那就是如果说上一个交易发送成功的话。我们按道理拿到的就应该是该发下一个,那但这个这个过程当中,我们是需要设置好时间,或者说别的一些逻辑的,你不能很快的发,很快的发的话,你一定查出来的是都没镜块,那可能刚才刚发了一个nu是实的,然后你又要发下一个,然后发现,诶现在好像这个NUS还是就是就是现在的nu还应该是发十,那我就继续发十,这肯定是不行的,肯定我们还要结合本地已经发送的这些交易,对吧,自己已经发出去的,你应该再加一,就是这样的一个过程。
29:11
他的问题在于还是有单点故障可能,那我们这个节点全靠他跟踪档次来分配啊,全靠他去去签名交易啊,他如果挂了的话,这些也是实现不了的。而且他跟踪这个闹和签名的这个节点就是这这种方案在某种意义上说可能是实现并发了。哪种意义上实现并发了呢?就是我们的ma mask和和我们的盖这里是确实是可以同时去生成交易的,确实是可以同时把交易提出来的,但是呢,就是他们生成交易的这个动作是同时的,看起来好像是同时提起来了,但是确认他没办法同时确认确认的过程。
30:02
发放浪子的过程,最终这个签名的过程,它并不是并发的,它最终还是一个一个排在队列里面,一个一个上面的,所以大家可以看到,就是以太坊引入了浪子之后,尽管解决了重放攻击,但是同时带来的一个问题就是。它的并发性下降了,它其实我们至少这两种方案里边,我们看不出来他在真正意义上有并发,对吧,就是你最后的真正的上链还是要一个一个排着队上,这就不存在并发了,这不是顺序执行嘛,所以呃,我我们就是能够发现解决了重放攻击之后,为了解决重放攻击引入的浪其实也不是完美的,呃,当然就是说整个社区还有很多开发人员也都在想各种各样的改进方案,那之后会到底变成一个什么样,可能还会变成有很多天才的想法,有很多很很神奇的东西出现,那我们再看之后的这个这个整个行业的发展方向啊。
我来说两句