前言:Qtum量子链致力于搭建比特币生态和以太坊生态的桥梁,通过基于激励的权益证明机制来作为Qtum的共识机制,并以比特币的UTXO模型为基础,支持图灵完备的虚拟机(例如Qtum VM/EVM/Lua 等)并通过移动端的战略,搭建基于区块链技术的DAPP和智能合约的移动端应用,通过DAPP Store(去中心化应用商店)的高效和快捷的分发,促进区块链技术走向普通互联网用户。
除此之外,Qtum还创新性的提出了价值传输协议的概念(VTP协议:Value Transfer Protocol),通过智能合约内嵌到协议层,通过不同的用户地址权限和地址类型的管理,以及结合万维网的标准,来实现一种融合现有TCP/IP协议的区块链支付协议,并且该支付协议将带来更多的智能和更多的商业可能性。
如何实现这个宏大的愿景,需要无数的开发者的心血持续的投入,Qtum的开发团队是一个非常国际化的团队,也正符合区块链技术的分布式的特点,截止本文发稿时,已经累计有29位开发者参与到Qtum的项目开发过程中,如何协调不同国家,不同时区的开发者也是区块链项目开发过程中面临的一个难题,除了可以通过github进行协同开发以外,Qtum团队还采取了了很多其他协作工具,包括自己开发了一些协作工作,包括代码共享、代码测试、代码环境迁移等。
今天,让我们一起和Qtum的团队回到几个月之前,重温当时Qtum虚拟机(QVM:Qtum Virtual Machine)中关于GAS机制的设计过程,为了让大家更好的任何和理解区块链技术的开发过程和工作方式,更好的认识区块链开发者,我们原汁原味的保留了当时团队关于GAS机制的讨论过程,和GAS1.0 设计完成之后,被推倒重来的过程,希望这些开发细节的公布可以给其他的区块链开发团队和区块链开发项目带来一定的帮助,并提高项目的开发效率,也希望通过相关细节的公布,让大家可以走进区块链的开发团队,进一步和Qtum的开发团队有更多的交流。
参与GAS机制设计的团队成员如下:第一排 第二排 从左到右
帅初:Qtum发起人,毕业于Draper University(英雄学院)和中国科学院,之前就职于阿里巴巴,博士期间就致力于区块链技术的开发和研究,具备丰富的区块链行业的开发经验。
John: 毕业于University of Florida,之前就职于Bitwage,Coinpip等区块链公司。
欧阳韵奇:毕业于北京邮电大学,之前就职于百度,亚洲魔方比赛冠军。
Neil: 15年软件开发经验,精通比特币和以太坊的开发和设计,白帽开发者。
百强:北大理论物理专业辍学,之前就职于金山软件和猎豹移动。
Jordan.earlz: 13岁编程,18年开发经验,Coin Reviewer,Review过社区100多种虚拟货币的设计,安全专家,北美比特币社区最有名的开发者之一。
Emiliano:计算机科学博士,data feed 和 data mining 专业。
IBai: 密码学专家,密码学博士,区块链社区早期参与者和开发者
Qtum(中国成员)开发团队上海办公室
·alex :Hi,大家好。关于GAS机制我们最终的设计是什么?
·earlz :我们选取目前的设计机制,使用bitcoin的手续费机制(例如:输入—输出=矿工费用),并且完成MAX_GAS的opcode, 这样矿工可以预先决定执行一个合约需要的工作量。
这里是关于MAX_GAS的设计机制 https://qtumproject.atlassian.net/browse/QTUM-7
·neo: hi 早上好
·earlz :Neo 早上好
·alex:谢谢,这里已经晚上了 哈哈
·earlz :这个GAS设计机制,你感觉如何alex?
·earlz :需要大家确定我们的设计目的,并且关于这个设计大家的认识是一样的。
·shuaichu:不大确定重新发行一个新的token来执行合约是否是一个好的想法?
·earlz :并不是发行一个新的token,而是仅仅是一个计数单位。Max gas的操作码仅仅是为了帮助矿工知道一笔交易需要的计算量是多少
·alex:是的,max gas并不是一个新的token
·shuaichu:我认为我们需要通过经济学方面的设计来执行操作符,类似于手续费的机制,并且需要注意的是网络中所有的节点都需要执行同样的操作符,如果执行合约是免费的,有些人可能会ddos这个网络
·earlz :这个方面我们可以设计,并且让所有的交易都包含一定的gas 费用(比如极端的情况是,直接损耗掉这些手续费,矿工也无法得到这些手续费),但是这种情况下,我们需要确定货币本身不能太通缩。
这种想法还可以,这样子的话,我们可以把一部分的GAS 费用给矿工,另外一部分直接损耗掉作为节点的费用,这样恶意节点的激励还大大减少。
·shuaichu:我觉得我们应该采用比特币类似的手续费机制,这样每一个操作符在Qtum的虚拟机中需要支付少量的手续费
·earlz :是的,但是我说的是矿工不能拿走所有的手续费,因为需要支付一些给GAS cost.
·shuaichu:如果一笔交易中的手续费不够多,我们就需要丢弃这笔交易。
并且通过允许发送者设置更高的手续费来加速他们的交易。
·earlz :是的,矿工依然可以创造手续费高的交易
·alex:利用GAS 和MAX_GAS 的机制和OP_EXEC的优劣在于哪里?
·earlz :我不大确定利用MAX_GAS会带来不好的影响,其他的选择也许会导致矿工需要根据交易数据的大小来确定一笔交易是否昂贵,并且影响对是否打包进入区块的判断。
·shuaichu:我认为不好的地方在于gas本身是免费的,并且和qtum本身没有太多关系
·earlz :我认为这样的话,就会和以太坊类似,只是一个不同的代码实现方式,如果在以太坊中,所有的GAS被矿工获取,那么在Qtum中也一样,只是不同的是在以太坊中是通过“gas price”实现的,在Qtum中是通过 gas amount 和交易费用实现的。
·alex:是的,我们一earlz的看法,我认为GAS应该来自于以太坊网络,并且价值也取决于qtum的成本
·earlz :GAS只是一个数字,并没有任何价值,只是一个计算单位而已,当你构造一笔交易的时候,你需要声称这笔交易需要多少GAS(例如需要多少操作符的计算),如果你的交易花费了更多了GAS,那么这笔交易就会归为OutOfGasException,这里是类似于以太坊的,这样可以允许矿工通过查看交易费用来最终决定是否值得挖矿。
是的,GAS可能会根据qtum的价格,以及Qtum网络的状态来调整,类似于比特币网络中的交易费模型。
·alex:我认为GAS应该是交易费用的一部分,会在bytecode执行的时候消耗。
·shuaichu:Earlz, gas 来源于哪里?
·alex:gas应该来自于交易费用
·earlz :从技术上说,gas其实并不来自于任何地方,只是矿工的一种测量方法,来决定某个特定的交易费用是否值得挖矿。
·shuaichu:但是如果一个矿工把所有的交易都设置成最大可允许的gas,这样是否会引起对网络的dos,因为miner可以免费得到所有的gas
·earlz :这也是为什么MAX_GAS 是由交易的发起者设置的,而不是矿工本身。MAX_GAS 是包含在交易中的一部分,并且是不能被操控的。
·shuaichu:这个是的,但是如果如果交易发起者,每次都设置的一个非常高的值会有影响吗?
·earlz :如果他们设置的非常高,也就意味着矿工可能会不接受这笔交易,除非他们有一笔不菲的手续费。
·shuaichu:我知道了,所以最终还是取决于交易费用(我的理解)
·earlz :是的
·shuaichu:那么为什么不单单基于交易费用来设计这一部分的机制?
·earlz :因为没有gas和max gas的标记,矿工不会知道一笔交易最终要花费多少钱?
·shuaichu:比如类似于以太坊做一个固定的gas 价格
·alex:tx fee = inputs – outputs – gas price for all bytecodes executions
·shuaichu:因为如果用户设置了max gas,并没有一种方式可以决定最终的计算成本。
·earlz :在比特币的系统中,交易费的设计机制是ok的,但是这种语言并不是图灵完备的,不能够进行循环运算。这样的话,交易的数量大的大小是一个非常不错的指示来告诉矿工处理这笔交易所需要的时间,但是对Qtum的虚拟机来说,一笔很小的交易可能会花费非常多的时间去处理。比如这笔交易涉及的操作符包括循环等。
·shuaichu:计算的成本取决于最终执行了多少操作符,并且取决于执行的状态。
·earlz :如果没有max_gas的限制,一个攻击者会非常容易去攻击Qtum的网络,需要处理很多手续费很少的交易,并且矿工可能因为手续费太低而不执行相应的打包交易。通过max_gas,会比较容易决定一笔交易是否昂贵,矿工就可以提前决定是否处理这笔交易。
·shuaichu:这个方法会带来一些问题,因为我们不能信任一个交易的发起方设置的一个值。
·earlz :对于Max_gas来说,每一个opcode操作符都会消耗一定量的gas,如果一笔交易花费的gas超出了他们声称的max-gas,那么整个Qtum虚拟机的执行都会回滚,并且通过OutOfGasException的方式回滚,然而一笔交易依然会被区块链网络接受,并且矿工也会得到相应的费用。
·shuaichu:并且和Eth类似,当给出的手续费不能覆盖相应的费用的时候,虚拟机的运转会停止。
·earlz :是的,如果他们使用了错误的Max-gas,那么他们就有风险丢失所有的一笔交易里面所有的资金,这个也是目前OP_EXEC_ASSIGN 操作符的一个问题所在。这个也是一个需要考虑的情况,因为在UTXO模型里面,并不是很容易把资金直接退回。
所以可能我们需要设计一个 返回地址给OP_EXEC_ASSIGN 这个操作符。
·shuaichu:我认为在outofgas的例子中,我们可以设计网络依然收取相应的手续费,但是把其他的资金发送到发送者的地址中。
这样的话,outofgas 就会创造一个新的交易
·earlz :是的,但是问题是有时候发送者的地址并不是一个简单的地址,而是可能是一个多重签名(multisig)的地址或者是一个支付给脚本的地址(P2SH)
·shuaichu:但是在max gas的模型里面,Qtum的区块链网络如何收取fees?
·earlz :在max-gas的模型里面,手续费的收取可以类似比特币的手续费模型,就是输入大于输出,中间的差额就是手续费。
·shuaichu:那么这样的话,手续费应该包含在一个区块里面,那么也就意味着这笔交易被打包到区块链网络里面了。
·earlz :是的
·shuaichu:被拒绝的交易不会包含在区块链里面,这样的话他们的手续费也就很难收取。
·earlz :如果一个EVM的交易没有gas了,这笔交易依然是有效的并且会被包含在区块里面,但是不会执行虚拟机任何的操作,但是在我们的现阶段的QVM当中,这笔交易的发起人会损失一部分的资金,这个是我们设计上的缺点,我们需要通过一个 返回地址来更正这个缺点。
·shuaichu:我认为maxgas的想法并不能解决这个问题,和用fee的概念是类似的。
这个是一个主要的问题,如果用一个返回地址会带来系统的复杂度。也许我们可以找到更简单的实现方式。
·earlz :我们需要找到其他的可选的方式,这样我们可以保持和比特币生态UTXO模型的兼容性。
·shuaichu:这个确实是的。我们需要好好思考这个问题。
·earlz :是的,我们需要认真思考这个问题,我还没有去测试所有的可能性(edge case), 我的初衷是在 OutOfGasException的时候,可以把fee花费掉(给miner),但是其他的资金并不能丢失。
其他人如何考虑这个问题?
·shuaichu:我在思考这种情况
·也许睡觉的时候在想想 哈哈
·earlz :是的
·shuaichu:需要我们好好总结一下现在遇到的各种问题
·earlz :我感觉max-gas的想法可以继续借鉴,但是与在outofgas的时候,资金丢失相反,我们可以把这笔资金发送到一个目标合约,但是一个问题是,QVM并没有执行完成这笔交易。
哈哈,如果EVM关于处理gas的机制不是那么糟糕
目前看来,outofgas的交易应该是这样的
消耗手续费:意思是创造一笔交易,并且把这笔交易添加到一个区块链(意思是花费掉输入,并且创造新的输出,并且把新的输出给发送者,但是在p2sh的情况下,我们无法知道发送者是谁)
·earlz :我们可能需要设计 max-gas和warning-gas的部分,并且warning-gas的会触发程序预判目前的虚拟机的执行状况,并且告诉虚拟机下一步做什么?
·shuaichu:我认为max-gas的想法,其实和fee想法是类似的。
·earlz :是的
Max-gas的想法是给矿工稍微多一点点的信息,这样他们可以在没有执行合约之前,就可以预判这笔交易的gas是多少
·shuaichu:但是这个会带来一个问题,就是矿工其实并不知道实际的花费是多少,比如在blockx的时候消耗是1, 但是在blockx+1的时候,消耗是1000。并且contract的一些值的改变,可能导致程序指向一个更复杂的合约。
·earlz :是的,这个也是max-gas存在的原因,这样的话我们可以预测需要的执行时间是多少
·shuaichu:我觉得我们不在聊同一个事情啊 哈哈
比如说我们有这样一个合约
我们写一些伪代码 smile:
·earlz :是的 需要一个白板一起写一下
·shuaichu:slightly_smiling_face:
·earlz :是的,我知道你的意思,就是同一个合约在不同的区块执行会花费不同的gas(这个取决于在区块链网络中的哪一步被接受,以及如何如何执行的),
max-gas 可以设立一个上限,并且可以可以估计需要的计算量,当创建一个交易的时候,我们需要好好的计划,从而可以避免目前ETH系统中面临的问题(可以看看目前Ethereum 因为gas机制的设计面临的各种各样的问题)
·shuaichu:
int a=0;
void increment(){
a++;
return;
}
void weirdcalc(){
if(a==0){
return;
}else{
int i;
for(i=0;i<10000;i++)a++;
return;
}
}
·shuaichu:其中weirdcalc()取决于每一次的执行时间。我认为你应该知道我的意思
·earlz :是的
·shuaichu:问题是非常难以决定一个具体的上限。这样的话,只能通过盲目的执行来决定多少gas被消耗
·earlz :恩,是的,这样的话,所有的合约都必须通过一个可以预测gas的方式来书写
·shuaichu:是的,但是我们没有办法控制别人在书写什么。我们需要考虑到所有可能性,包括最坏的可能性。
·earlz :是的,如果他们不能通过一种可以预测的方式来决定一个合约需要多少gas的话,那么在QVM中就会和EVM面临相同的问题,并且会丢失掉他们的手续费,类似于在Ethereum中 outofgas 的情形。
·shuaichu:是的,我觉得我们需要关注的主要问题是:1 收取相应的手续费 2 返回相应的输入。这个是在目前的解决方案下,所面临的主要问题。
·earlz :好的
·shuaichu:然后我们需要决定看max gas的方式对应于gas的方式是否有任何优势。
其中一种方式是我们可以把fee发送到一个单独的交易
并且需要注意的是,因为我们会拓展EVM,那么一笔交易可以检查需要消耗多少GAS,并且可以根据这些情况来改变他们的行为。
·shuaichu:拓展的EVM?
·earlz :是的 链接在这里:https://github.com/bitsegroup/qtum-evm/blob/master/docs/dev-doc.md#opcount
我也很好奇为什么EVM没有这样的计法
·shuaichu:是的,这样有一定的好处,但是我们可以先专注到经典的VM,然后我们在原型完成之后,再测试。
我觉得我们需要弄清楚关于fees的一些难题
·earlz :是的,添加opcode并不是一件特别难的事情,难点在于如果与现有的solidity融合,并且保证其安全性。
但是不论如何,还是不能解决关于如何退回returning money 的问题。
明天可以继续考虑如何解决这个问题,估计睡一觉起来,会有一些新的思路。
哈哈O(∩_∩)O哈哈~
欢迎关注近期发布:
Qtum虚拟机(QVM)中关于GAS机制的设计(二)
下图是量子链虚拟机中关于GAS机制的第一版的设计草图,目前已经有较大的修改,在下一篇文章中,我们也会进一步剖析整个设计过程,敬请关注。