量子链账户抽象层分析

作者: ttblack | 来源:发表于2018-09-28 13:48 被阅读61次

    我们知道比特币的余额模型是UTXO模型,以太坊是个账户余额模型。这点可以从各自的交易结构里体现出来

    而量子链打通了这两个交易,实现了从UTXO模型到Balance模型的转换。这个转换过程称为:账户抽象层(Account Abstract Layer, AAL)。

    以太坊和比特币交易结构

    这里我们说下从UTXO到Balance的转换原理:

    1.UTXO交易新增的脚本操作码:Qtum 针对UTXO交易脚本新增了三个操作码OP_CREATE,OP_CALL和OP_SPEND,目的是用于为UTXO和EVM账户模型之间的转换提供操作支持。这些操作码定义在opcodetype枚举类型中(同比特币在script.h中)。

    2.量子链实现了一个自己的交易结构QtumTransaction,并且继承了以太坊的交易,同时扩展出用于生成UTXO结构的nVout和version两个字段 。(QtumTransaction.h)

    3.实现QtumTxConverter类,也就是用于转换的类及账户抽象层。(在validation.h中)

    4.实现EthTransactionParams 结构体,用于转换过程中参数的存储和传递。(在validation.h中)

    新增opcode

    OP_CREATE:用于智能合约的创建;OP_CALL用于合约的执行;OP_SPEND用于合约余额的花费;

    这些 OpCode的执行同比特币一样也是在EvalScript()中判断执行的(在interpreter.cpp中)。相当于比特币的虚拟机。

    在EvalScript中的处理

    从代码中可以看到,对OP_CREATE,OP_CALL的处理就是将剩余代码压栈。为了识别这几个操作符,Qtum扩展了在比特币交易类(CTransaction)中增加了HasCreateOrCall()和HasOpSpend()函数,用于新区块中对mempool中的交易处理。

    通过以上源码可以看到OP_CREATE,OP_CALL对应的交易输出,OP_SPEND对应的交易输入也就是用于余额的花费。

    现在我们就开始从源码看下具体的转换过程,代码从validation.cpp中验证函数(AcceptToMemoryPoolWorker)开始,从源码可以看出,qtum就是在比特币的源码基础上增加了HashCreateOrCall()的判断。并进行了处理。

    调用AAL层进行转换

    CheckSenderScript()是先检查了解锁脚本是否合法。核心转换代码在QtumTxConverter中的extractionQtumTransactions 函数中。

    extractionQtumTransactions

    可以看到这个函数是遍历了交易输出的锁定脚本也就是智能合约代码。

    1。判断是否有OP_CREATE和OP_CALL,通过receiveStack将脚本传入堆栈,并判断执行结果

    2。通过parseEthTXParams提取转换到以太坊交易所需的参数。

    3。通过createEthTX将参数转入,并且转换成QtumTransaction,我们知道QtumTransaction就是继承自以太坊交易的。所以和EVM执行相关的操作QtumTransaction类都支持。

    以上三步的三个函数都在QtumTxConverter类中。具体文件是validation.cpp。

    将脚本存入stack栈

    上面代码将传进来的合约脚本通过EvalScript存入stack中。并进行了有效性判断。下面是从stack中取参数。

    提取转换参数

    以上代码首先判断如果opcode 为OP_CALL,则说明地址为vecAddr的合约已经创建,因此直接转换成EVM格式的地址receiveAddress,否则为OP_CREATE,对应合约的创建,没有该字段,所以不做提取。接下来依次完成了data、gasPrice、gasLimit、VM version的提取,提取操作就是顺序将stack中的数据出栈就可以了。这些都是EVM执行bytecode时必不可少的参数。

    利用参数生成QtumTransaction

    首先代码etp.receiveAddress == dev::Address()判断该合约是EVM状态中没有而需要新创建的还是EVM状态已经包含的合约,差别只在于合约地址。然后,QtumTransaction()构造函数完成了部分的交易参数构造,接下来的语句提取交易的发送者(sender),之后设置交易HASH。一个UTXO交易支持多个输入和输出,Qtum的AAL设计考虑到了这种情况,因此AAL支持一个交易输出包含UTXO账号和合约账号,通过最后设置的nOut指示该交易的nOut输出是发送到智能合约的(对应交易输入所引用的utxo顺序号COutPoint的n),所以该输出将触发合约执行。这样就按照EVM的账号模型完成了交易的转换。

    好了,以上也是将原理和实现从源码上分析了下,至于从Balance到UTXO的转换,代码还要细细分析。

    作者:区块链研习社比特币源码研读班,black

    相关文章

      网友评论

      • ea90f5b41cd0:您好啊,这篇文章看后很有收获,不知道是否能得到一个您方便的联系方式和您讨论一下呢?谢谢
        ttblack:我微信号 zxb19851209 我也是看了一点。太细节的也不太懂
      • 信渤科技区块链:第一时间分享大伽新作到本人技木群

      本文标题:量子链账户抽象层分析

      本文链接:https://www.haomeiwen.com/subject/gwuuoftx.html