zoukankan      html  css  js  c++  java
  • PalletOne调色板跨链的BTC实现

    之前已经讲到了PalletOne调色板跨链以太坊ETH和ERC20的技术原理,接下来我们来讲解PalletOne跨链比特币BTC的技术原理。

    一、BTC充币

    假如用户A持有一定数量的比特币BTC,他希望换一些PTN,那么他可以通过BTC充币合约,将BTC兑换成等值的PBTC(PalletOne上发行的与BTC1:1兑换的映射Token),然后用PBTC即可与持有PTN的用户进行互换。BTC充币合约是运行在一个选定的陪审团上的用户合约,陪审团由4个选出的陪审员组成,每个陪审员都部署了PalletOne的比特币适配器,通过BTC-Adaptor,合约可以对比特币网络进行访问和操作。

    0.选定陪审团,每个陪审员节点生成比特币的私钥、公钥

    在BTC充币合约部署到PalletOne网络时,会选定4个陪审员组成陪审团,每个陪审员因为都有比特币适配器,所以可以按比特币的规则,生成私钥和公钥,并将公钥公布到PalletOne网络(记录到状态数据库)。

    1.生成锁定BTC的多签地址和赎回脚本

    我们规定,4个陪审员,只要有3个同意将多签合约中的BTC转移,那么该交易就可以生效,所以我们需要构建一个3/4签名的多签脚本和地址。

    该多签脚本又叫做赎回脚本 Redeem Script,格式为:

    3 PubKey1 PubKey2 PubKey3 PubKey4 4 CHECKMULTISIG

    对该赎回脚本计算Hash,即可得到P2SH的地址: 3XXXXXXX

    这个赎回脚本和多签地址是固定不变,都需要保存到PalletOne的状态数据库中。

    2.用户将自己的BTC转移到多签地址进行锁定,并通过OP_RETURN备注上映射的PalletOne地址

    前面我们已经得到了多签地址3XXXXXX,将BTC转移到该地址即可实现BTC的锁定,但是比特币是不支持智能合约,怎么才能做PalletOne地址的映射呢?幸好比特币有OP_RETURN功能,这个特殊的OP CODE就是为了在交易时存放额外数据用的,这额外的数据可以是比特币转账时的备注信息,可以是存证一些信息,也可以做商业上的一些特殊扩展应用。OP_RETURN后面的数据限制为40字节(或者80字节,取决与Bitcoin core的版本),PalletOne地址为20字节,进行Base58编码后,显示的字符串长度最长为35位,满足40字节的限制要求,所以我们可以直接将PalletOne地址以字符串形式放到OP_RETURN中。

    【扩展方案:由于PalletOne地址是和比特币地址的生成规则类似的,所以一个合法的PalletOne地址,在去掉第一个字母P后,就是一个合法的比特币P2PKH地址,于是我们还有第二种映射方法,那就是在把BTC转移到多签锁定地址的同时,也将1聪的BTC转移到去掉第一个字母P的PalletOne地址而产生的映射地址上,那么BTC充币合约在扫描交易的时候便可读取该地址,从而得到映射地址。】

    3.定时任务扫描多签地址上的交易,发起PalletOne合约放币

    用户在将BTC从自己的钱包转移到多签地址的交易被打包确认后,定时任务会扫描到该笔交易,然后将该交易的Hash作为参数,发起对BTC充币合约的“放币”方法的调用,而参数就是该锁定BTC交易的Hash。如果锁定比特币的交易未被打包,或者打包后的确认数不足(小于6个),则不发起放币方法的调用。

    4.PalletOne合约确认多签地址收到BTC,释放对应数量的PBTC到映射地址。

    合约的内部逻辑是这样的:

    1. 根据传入的Hash检查StateDB,确保之前没有处理过该笔交易。
    2. 通过BTC-Adaptor读取到该笔交易的详细信息,获得对应的映射地址、BTC金额、接收地址等。
    3. 确认接收地址为多签锁定地址所收到的BTC,生成从合约付款PBTC到映射地址的Payment。
    4. 记录下比特币锁定的Hash,防止重放攻击。

    以上步骤最终以一个Transaction的形式完成,所以不存在部分完成的可能。

    二、BTC提币

    如果用户已经持有了PalletOne上面的BTC等值映射Token:PBTC,现在需要兑换成BTC(也就是提币),那么应该按如下方式实现:

    1.将PBTC转移到PalletOne上部署的BTC提币合约(我们命名为PC1),同时在该交易上,以比特币收币地址作为附言。

    用户B通过和用户A交易,拿到了1 PBTC,如果要转换为BTC,需要先准备一个BTC的钱包,并获得自己接收BTC的地址。接下来,在PalletOne中发起一笔交易,该交易包含了以下两条主要消息:

    • 将1 PBTC转移到提币合约PC1上
    • 在交易的Data Message上,写入了用户B的比特币钱包地址。

    2.陪审团从比特币多签地址上选取适当的UTXO,构造付款到提币地址的交易并签名。

    定时任务扫描BTC提币合约上的交易,一旦发现有转入PBTC进行锁定的交易,即发起对提币合约的提币请求。陪审团在接收到发起的请求后,会通过BTC-Adaptor查询多签锁定地址的UTXO,在获得UTXO后,还需要进行过滤。因为之前可能有其他的提币申请,而且没有被签名或者没有被打包,但是这些提币申请在PalletOne提币合约中已经记录下来,所以我们需要将这些被“预定”了的UTXO排除掉,不然可能会造成两笔不同的提币交易双花同一个UTXO的情况。过滤完UTXO后,剩下的UTXO我们通过一定的算法,找出其中满足交易提币额,而且尽量接近提币额的UTXO,这些UTXO就是比特币交易的输入。已知用户提币的金额(=打入到PC1合约的PBTC金额-提币手续费)和提币地址,就可以构造比特币交易的输出。这样未签名的比特币提币交易就完成了。当然陪审团还会把本次提币交易所使用的UTXO记录的到状态数据库中,表示已经被占用,以防新的提币交易使用同一个UTXO。

    在选取UTXO时,需要注意,如果有多人发起了提币,那么可能出现UTXO被暂时占用完的情况,也就是说本次提币交易无法获得足够的UTXO来构造提币交易,那么这次提币交易就会失败,用户转到合约的PBTC也会返回到用户手中。用户只有等一段时间,让之前被预定的UTXO被签名打包了,产生了新的找零UTXO,再次发起提币交易才能成功。

    如果提币交易构造顺利,陪审团会进行进一步的操作:

    1. 陪审员用自己的私钥,对提币交易进行签名。
    2. 4个陪审员进行协商,按一定规则筛选出3个陪审员签名。
    3. 陪审员用3个签名,还有之前已经生成并保存好的赎回脚本,构造完整的解锁脚本: Sig1 Sig2 Sig3 RedeemScript
    4. 将解锁脚本和未签名交易结合,形成可被比特币网络接收的已签名交易并保存到PalletOne状态数据库中。

    3.比特币广播节点监测PalletOne网络,发现有签名后的比特币交易,将该交易广播到比特币网络。

    在PalletOne网络中,我们还需要部署一些比特币交易广播节点,这些节点监测PalletOne网络,发现有已签名的交易保存到状态数据库时,就会将该交易取出,然后广播到比特币网络。该节点还负责查询已签名交易的打包状态,如果已经被打包和确认,那么就可以向提币合约发起一个“交易状态更新”的方法调用,将该提币交易状态改为已打包,陪审员也会通过BTC-Adaptor确认状态是否真实,如果真实,将UTXO状态和交易和状态进行更新。

    三、总结

    比特币的模型是UTXO,与以太坊的Account模型不同,所以在BTC提币的时候,步骤2需要预先独占用一部分UTXO,如果某次提币操作占用的UTXO过多,剩余的可用UTXO过少,可能会导致接下来一段时间BTC提币失败。

    比特币的手续费是从转出的地址中收取,而不是像以太坊一样收取合约调用者的Gas,所以在BTC提币的时候,是没有比特币广播节点的补偿的。

    在地址映射上,除了使用OP_RETURN或者使用以太坊的transfer函数进行地址映射,都需要将映射地址写入到原有的链上,如果用户是一个区块链开发者,或者有高级的钱包工具,完全可以用自己比特币/以太坊的私钥对映射地址进行签名,然后将公钥、映射地址、签名这3个信息提交到跨链合约,合约是可以通过验证签名和公钥,确保映射地址的正确性。这种映射方式的好处是不需要在原有区块链上发布消息(降低了手续费),但是缺点也很明显,大部分用户只会用钱包APP进行转账操作,一般钱包APP也不提供签名、导出公钥等操作。

    对于要转网的用户来说,他们永远只是做了地址映射和转Token到指定锁定地址两个操作,如果链支持在转账交易时附言,就是一步操作即可这两件事。合约调用之类的复杂操作一般钱包APP不支持,所以都是留给后台定时任务来完成。

  • 相关阅读:
    easy ui 表单ajax和from两种提交数据方法
    easy ui 下拉级联效果 ,下拉框绑定数据select控件
    easy ui 下拉框绑定数据select控件
    easy ui 异步上传文件,跨域
    easy ui 菜单和按钮(Menu and Button)
    HTTP 错误 404.3
    EXTJS4.2 后台管理菜单栏
    HTML 背景图片自适应
    easy ui 表单元素input控件后面加说明(红色)
    EXTJS 4.2 添加滚动条
  • 原文地址:https://www.cnblogs.com/studyzy/p/11929287.html
Copyright © 2011-2022 走看看