Qtum量子链QIP-5提案:在智能合约交易输出脚本上增加签名证明,允许用户以代付方式调用合约

Qtum量子链...

09-23



摘 要

Qtum量子链的主要目标之一是建立基于权益共识机制(PoS)、并支持 UTXO 的智能合约模型。在智能合约层面上,Qtum 量子链兼容比特币 UTXO 模型和符合 AAL 规范的虚拟机,其中第一个兼容的虚拟机是以太坊的 EVM ,后续将实现 x86 架构的虚拟机,支持多种流行的智能合约编程语言。Qtum 在智能合约的创建、运行、稳定性和可用性上一直在做大量探索与实践。


实现智能合约的区块链平台,不管是 Qtum 还是 Ethereum,都设计了 Gas 模型来避免智能合约的调用耗尽区块链资源导致整个系统崩溃。但这也带来了一个问题:一个地址想要操作智能合约,则必须自己支付 Gas 并判定身份。在 Qtum 区块链中是通过检查作为交易输入的 UTXO 来判断合约操作者的,这就意味着一个地址必须拥有可支付 Gas 的 QTUM才能进行合约调用,这给普通智能合约用户和交易所等机构都带来了一些难题。


为了解决这一问题,QIP-5 提出在 Qtum 链上加入 OP_SENDER 操作码,使得一个地址可以在没有 QTUM(UTXOs)的情况下通过别人代付 Gas 的方式调用智能合约。具体实现点击阅读原文:相关链接


Qtum 链上智能合约的相关实现


01 AAL 实现 UTXO 与 EVM 的适配



Qtum 为了增加 UTXO 的灵活性和功能复杂性,选择将智能合约虚拟机迁移到 UTXO 模型之上,第一个集成的虚拟机是 EVM。EVM 使用了256比特长度的机器码,是一种基于堆栈的虚拟机,用于执行 Solidity 智能合约。Qtum 使用账户抽象层(Account Abstraction Layer),将 UTXO 模型转换成可供 EVM 执行的账户模型,并加入了基于账户的接口,使EVM 可以直接读取 Qtum 链上的信息。详情见:《深度解析Qtum量子链账户抽象层(Qtum AAL)


02 OP_CALL 与 OP_CREATE 处理智能合约操作



比特币支持五种标准交易操作码:P2PKH(Pay to Public Key Hash)、P2PK(Pay to Public Key)、多重签名(少于 15 个私钥签名)、P2SH(Pay to Script Hash)和 OP_RETURN。利用这五种交易标准,比特币客户端可以满足复杂的支付逻辑。Qtum 在此基础上增加了三个全新的操作符来支持合约余额的查询以及为合约发送资金等操作:

•OP_CREATE – 用于执行智能合约的创建,把通过交易传输的字节代码传递到虚拟机的合约存储 数据库,并生成一个合约地址;

•OP_CALL – 用于传递调用智能合约所需要的相关数据和地址信息,并执行合约中的代码内容。该操作符还可为智能合约发送资金;

•OP_SPEND – 将当前合约的 ID 哈希值作为输入的交易HASH,或发送到合约的 UTXO 的交易HASH,然后使用 OP_SPEND 作为花费指令构建交易脚本。


引入 OP_SENDER 操作码


01 现实需求


AAL 支持一个交易输出包含 UTXO 地址和合约地址,OP_CALL 和 OP_CREAT 操作码会触发合约执行。那么我们如何获取合约交易的 sender 呢?现有的共识规定,若一笔交易带有 OP_CALL 操作符,则该笔交易的第一个输入 vin[0] 对应的地址作为合约调用地址,而一个合法的输入必须余额大于0,目前这是获得 sender 信息的唯一方法。即 AAL 通过分析交易的第一个输入的 UTXO,并检查 UTXO 的地址是否在此交易中花费了代币来确定合约调用方(并对其进行身份验证)。这就意味着如果一个地址没有足够可用的 UTXO(没有QTUM余额),将无法验证该地址向合约发送的执行消息,即无 UTXO 的地址无法进行合约调用。


我们来分析钱包的情况。一个钱包可以导入很多地址,也会为了找零生成很多新的地址,这些地址都有自己的一组 UTXOs。但是整个区块链系统无法识别这些地址属于同一个钱包,只以地址区分权限和身份。因此,当一笔 QRC20 的合约代币转入到某个地址,尽管这个地址属于一个钱包,且钱包内有足够的 QTUM,但是该地址本身并没有 UTXO,那这些 QRC20 代币也同样无法使用。因为没有一笔属于该地址的 UTXO 作为调用合约的输入,即无法向合约发送证明自己可以转移 QRC20 代币的交易。这种情况的解决方案一般是给这个有 QRC20 的地址转入一笔 QTUM 来保证其可以调用合约。这一限制给 QRC20 代币用户带来了很大的麻烦:用户不仅需要关注 QRC20 代币,还需要为 QRC20 代币的相关操作维护地址的 QTUM 余额管理。


02  引入 OP_SENDER 操作码



在 QIP-5 (Qtum Improvement Proposals-5)中,我们提出了一个改进提案--为合约交易在输出脚本中增加签名证明。这个提案将允许用户在没有 QTUM(UTXOs)的情况下,对合约签名以及向合约证明自己的身份,即本身不支付 Gas 的前提下作为 sender 调用合约。该提案仅针对合约调用生效,它允许将 msg.sender 设置为无 QTUM(UTXOs)的地址。但是该提案并不意味着可以免费调用合约,必须有其他人(地址)为这笔交易支付相应的 Qtum 消耗。


OP_SENDER 的技术实现


01 OP_SENDER 操作码介绍



OPSENDER 操作码仅在包含 OPCALL 或者 OPCREATE 的输出脚本中生效,这是为了确保其只被用于智能合约相关的操作。对比 OP_CALL 选择 sender 的方式,QIP-5 提出了一种新的获取 sender 信息的方式:保留原有的规则,同时若输出脚本中带有 OP_SENDER 操作码,则选择输出脚本中传入的地址和签名作为合约的调用者,交易消耗的 Gas 可由他人代付,代付者提供调用合约所需要的 UTXO 并在输入脚本中签名。


OPSENDER 操作码包含三个参数:

  • UniversalAddress type -- 合约调用者(msg.sender)的类型
  • UniversalAddress data -- 合约调用者的数据(动态长度)
  • scriptSig -- 完成地址签名所必需的序列化scriptSig(脚本签名)

针对包含 OP_SENDER 的输出,我们给出一个例子:

  • 1 // pubkeyhash(公钥哈希)地址类型
  • Address// sender的pubkeyhash地址
  • {signature,pubkey} //序列化的scriptSig
  • OP_SENDER
  • 4 // EVM版本
  • 10 //gas price
  • 100000 //gas limit
  • 1234 //合约要发送的数据
  • Contract Address//合约地址
  • OP_CALL

OP_SENDER 操作码将会导致一次内部脚本的执行,如果该脚本执行的结果不是 1,则将返回执行失败,示例如下:

  • signature
  • pubkey
  • OP_DUP
  • OP_HASH160
  • address
  • OP_EQUALVERIFY
  • OP_CHECKSIG

上述序列化的 scriptSig 和普通的用于验证的 scriptSig处理方式相同。如果它的执行结果是 0,则该笔交易是无效的,这笔交易不会被打包进一个新的区块中。OP_SENDER 的验证脚本只在交易验证时使用,不会对合约的相关调用功能产生影响,验证通过的 sender 消息通过 AAL 的 QtumTxConverter ,转化为合约的 msg.sender。


02 OP_SENDER 签名


在OP_SENDER 中的签名是一个特例。通常在比特币和 Qtum 的 UTXO 模型中,只有 vin 输入的 scriptSig 脚本中包含签名,因此只需要简单地提出一个签名的方案来避免”签名已签名的数据“(重复签名)的问题。但是,QIP-5 打破了这个预设情况,在 vout 输出脚本中也加入了签名。因此,为了防止破坏现有的基于比特币脚本的签名范例,我们将签名设计为两个分开的步骤:

•为带有 OP_SENDER 操作码的 vouts 输出签名

•普通的 vin 输入签名

vin的签名过程将保持不变,同时 vout 输出签名也引入类似 segwit(隔离验证)的签名方式来实现。这种设计可能不是最完美的,但对于现有的比特币和 Qtum 区块链网络来说,这种设计更为安全和简单,且对之前的版本兼容性更强。

QIP-5提出的方案中,vin 的签名不受影响,vout 按照 segwit 方式进行签名并将 OP_SENDER 操作码引入到交易中,可以通过构建带有 OP_SENDER 的交易来实现无 QTUM UTXOs 的地址通过他人代付 Gas 的方式调用智能合约。


03 OP_SENDER 交易示例





如上图所示,我们已经在 Hard Fork 版本中增加了 OP_SENDER 操作码,并在为 Hard Fork 新建的测试网络中成功创建了带有 OP_SENDER 的交易。该笔交易包含了普通转账、Create、Call、Create_Sender、 Call_Sender多种交易。可以看出以下几点特征:

  • 对于输入脚本并未做任何修改,保留了之前的格式和签名
  • 在单笔交易中可以调用多个合约,图中带有 OP_SENDER 的两个输出指定了相同的 sender 地址,但我们支持为每个合约调用指定不同的 sender 地址;
  • 该笔交易包含多笔输出,包含普通转账、合约操作、带有 OP_SENDER 的合约操作
  • 对比图中的普通合约输出与 OP_SENDER 合约输出可以看出,合约相关的输出必须带有 OP_CALL 或者 OP_CREATE,OP_SENDER 需要在带有 OP_CALL 或者 OP_CREATE 的输出中才可以生效
  • 输出的格式与前面描述的输出示例相同,顺序是地址类型、sender 地址、序列化签名脚本、OP_SENDER 操作码、EVM 版本(升级后是4)、gas price、gas limit、合约数据、合约地址、OP_CREATE 或 OP_CALL 操作码


QIP-5 升级后的影响


01 技术上对 Qtum 网络的影响



由于 QIP-5 需要增加一个操作码来实现在输出中传入 sender,因此我们需要一次硬分叉来将其引入 Qtum 网络中。但是 QIP-5 只是添加了新的操作码,对之前的区块和交易是兼容的。


硬分叉在今年九月在测试网首先发布,经测试网大量测试无误后在十月正式更新到 Qtum 主网。



该次升级支持之前版本迭代的所有功能,QIP-5 设计的一些优点以及对 Qtum 网络的影响可归结如下:

  • QIP-5对共识的影响很小,因为引入 OP_SENDER 操作码只是对包含智能合约的交易产生影响,其他模块的代码未做任何修改
  • 带有 OP_SENDER 的交易与正常的智能合约交易保持相同的格式,不会引入新的交易格式
  • 允许单笔交易中执行多个合约,每个合约可以有不同的 sender
  • 可扩展性强,未来可以支持更多地址类型
  • 但在实现和使用时,也需要做一些额外的操作来保证其可用性:
  • 必须提供特殊的签名工具以及 RPC 接口来使用该功能
  • 在验证签名时必须为 OP_SENDER 解析并检查输出脚本。一般来说在做签名验证时是忽略输出脚本的


02 对用户的影响


由于 OP_SENDER 的引入,将会出现代付交易 Gas 的服务,以便于用户直接操作 Dapp 而无需关心自己是否有充足的 UTXOs 来支付 Gas 及验证权限,这对于 Dapp 生态和用户都是一项极大地便利:

  • Dapp 的维护者可以通过构建 OP_SENDER 交易自行做 Gas 代付服务,或者接入可信的 Gas 代付服务来为 Dapp 用户带来更加便利和简单的操作体验

  • 用户可以直接接入 Dapp 生态而无需考虑 QTUM 余额对地址操作的限制,降低了 Dapp 的使用门槛

  • Dapp 用户可以经常更换地址而无需为了支付 Gas 而向新地址转入 QTUM,这能有效地确保 Dapp 用户数字资产的安全性


03 对交易所的影响



交易所中流通着大量的 QRC20 代币,而交易所需要为每个 QRC20 用户创建一个 QTUM地址。维护这些地址且让这些地址可以进行充提币是比较复杂的。


一般的做法是维护冷热钱包,用户从链上转账 QRC20 到交易所中,交易所确认交易后会转移到热钱包中,长时间不动的 QRC20 代币会转移到冷钱包中。在从用户地址向热钱包转账时需要支付 Gas,因此即使该地址仅用于 QRC20 代币的转移和交易也需要保证其拥有一定数量的 QTUM 来实现 QRC20 转账。上述过程中,每个交易所会有不同的设计和风控,但总的来说都需要维护用户地址的 QTUM 余额来完成代币转账。


在引入 OP_SENDER 后操作码后,交易所不必再为操作智能合约代币的用户地址维护支付 Gas 的余额,而是可以通过构建 OPSENDER 交易的方式来进行用户地址到热钱包的转账,从而大大减少交易所维护用户地址、进行钱包整理的复杂度,有助于交易所提高效率和降低成本。


评论

暂无评论

推荐阅读

Qtum量子链

原创 首发

09-24

关注

Conflux中文社区

原创

10-30

关注

Qtum量子链

原创 首发

10-10

关注
关注
关注
关注

Qtum量子链

原创 首发

10-23

关注

Qtum量子链

原创

9小时前

关注

Qtum量子链

原创 首发

10-15

关注

万向区块链

原创

10-25

关注
加载更多