LocalCryptos的非保管式比特币托管是如何工作的

LocalCryptos 发布了 一个新的点对点加密货币市场。

2019年11月,LocalCryptos推出了比特币托管服务。 我们复制了基于Ethereum的概念,并将代码转换为一个与比特币兼容的脚本。

在本文中,我们将解释它是如何工作的。

本文假设你对比特币有一定程度的了解。 我们将尝试分解一些简单的概念,但是如果您不知道 “UTXO” 是什么意思,可能很难理解。

此设置从自始至终都是非监护的。 LocalCryptos的服务器只存储加密的blobs,无法与gibberish区分开来。 我们的服务器不会生成这里描述的任何交易—它是所有浏览器的JavaScript。

我们的根在Ethereum

在我们将平台重命名为LocalCryptos之前,我们是LocalEthereum。 LocalEthereum是世界上第一个针对Ethereum的p2p交易平台。 它也是PaxFul和LocalBitcoins之后最流行的P2P fiat-to-crypto通道。

LocalEthereum并不是一个简单的LocalBitcoins克隆。 虽然用户经历类似,但当您打开引擎盖时,LocalEthereum就是只野兽。 它是唯一一个端到端加密消息和非保管web钱包的平台。 它也是第一个引入“非保管式托管”的公司,这听起来有点矛盾。 让我们来解释一下这是什么意思:

它使用的是Ethereum智能合约,而不是在服务器的钱包中保存加密货币。 Ether(ETH)将从卖方流向智能合同,并从智能合同流向买方。 智能合约以一种分散的方式预先确定了托管的规则。 通过使用智能合约而不是托管人,代管无中介。

现在我们已经为比特币建立了同样的东西。 只是比特币没有智能合约——它有脚本。 脚本在某些方面类似于智能合约,但在其他方面则截然不同。

比特币交易是什么?

比特币交易包含输入和输出。 每个输出都包含一个收件人地址—您将比特币发送到何处—以及该地址将获得多少。 输入指向以前的输出——你还没有消费的硬币。

比特币“地址”是一个奇怪的概念。 在某种程度上,它们不是协议的一部分——中本聪的白皮书中没有提到它们。

1MoNS93aYgeuCcojcYbAJpKxqDN9UuJa9C

有不同类型的比特币地址。 比特币地址被解码后,包含两个部分:版本标识符和有效载荷。 版本字段在开始,它告诉你的比特币钱包的地址类型,它正在处理。 有效负载的使用取决于版本。

1开头的地址是 Pay-to-Public-Key-Hash (P2PKH) 地址,这是地址中最多的版本。 以3开头的地址是Pay-to-Script-Hash (P2SH) 地址,这是地址中最多的版本。 你可能还会看到其他地址前缀,例如本机SegWit地址。 就本文而言,只需要理解 P2SHP2PKH 地址。

Address标准描述了如何创建谜题(puzzles),以及如何创建解决方案来解锁它们。 谜题(puzzle )解决方案允许接收方使用输出作为另一个交易的输入。

爱丽丝用老方法给鲍勃送了一些钱

P2PKH地址中,版本之后的有效负载是接收方公钥的散列。 使用的散列函数是“hash160”,翻译成RIPEMD160(SHA256(thing))

当Alice想要向Bob发送一笔付款时,她创建了一个名为_ScriptPubKey_的谜题,只有Bob可以解开。 这个谜题变成了她的比特币交易的输出。

为了让Bob使用这些输出,他需要将其用作另一笔比特币交易的输入。 为此,他需要创建一个有效的 _ScriptSig_与_ScriptPubKey_对应。

任何 P2PKH _ScriptPubKey_都遵循这个模板:

OP_DUP OP_HASH160 <PubKeyHash> OP_EQUAL OP_CHECKSIG

对应的P2PKH ScriptSig 的格式为:

<Signature> <PubKey>

OP_Huh?

一个输出的_ScriptPubKey_ 是一段代码。 它是一种受限制的、基于堆栈的、比特币特有的编程语言,名为“Script”。

_ScriptSig_也是一段代码,但根据比特币的共识规则,它只能包含“推送数据”。 简单地说,它只能将任意数据添加到堆栈中。

在这个P2PKH示例中,Bob的_ScriptSig_向堆栈添加了两项内容:

检查ScriptSig是否正确

在矿机将这个交易包含在一个块中之前,它们将确认_ScriptSig_对于_ScriptPubKey_是正确的。

T矿工将_ScriptPubKey_添加到_ScriptSig_的末尾,并执行代码。 在运行最后一行代码之后,堆栈必须以顶部项为真(非零) 结束。 这就是验证_ScriptSig_的全部内容。

<Signature> <PubKey> OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

如您所见,堆栈以“true”结束。 如果您想了解更多关于P2PKH的信息,以及为什么它如此流行,web上有大量的资源。 在谷歌中搜索”P2PKH“可以找到更多信息。

什么是P2SH 地址?

付费到脚本散列(Pay-to-Script-Hash )地址将提供支付条件的责任转移给使用者。

还记得我刚才说过,花钱的人的_ScriptSig_不能包含非数据代码吗? 暂时忘记—P2SH改变了一切。

这些代码不是在_ScriptPubKey_中编写支出情况,而是进入_RedeemScript_中编写。 是的,这是一个新的术语——用不严谨的非技术术语来说,它指的是输出的“真正”谜题。 当你将硬币发送到P2SH地址时,_ScriptPubKey_包含一个消费密码的散列。 它是这样的:

OP_HASH160 <RedeemScriptHash> OP_EQUAL

一个P2SH的花费这在其_ScriptSig_中提供了两件事:

矿工将首先验证_RedeemScript_的哈希是否与_ScriptPubKey.中的哈希匹配。 如果是这样,它将解压缩_RedeemScript,将_Signature_放在其上方,然后执行。

什么是P2WSH地址?

LocalCryptos使用付款-见证-脚本-散列(Pay-to-Witness-Script-Hash) (P2WSH) 地址而不是P2SH作为托管。 确切地说,我们使用包装在P2WSH 内部的P2SH (即P2SH-P2WSH).

P2WSHP2SH的区别在于,在P2WSH中,旧的_RedeemScript_将进入一个新的“见证脚本”(Witness Script)字段。

如果您还不了解SegWit,请假想LocalCryptos的托管使用P2SH标准。 这也说得通。 使用隔离见证提高了托管的效率和成本,仅此而已。

为什么不使用多重签名?

假设LocalCryptos使用多个签名地址,这是一个很好的机会。 在代码中找不到 OP_CHECKMULTISIG

在多签名脚本中,每个签名者都是交易支出的一方。 在我们的模型中,LocalCryptos从来不需要在交易的任何部分签名——即使是在付款争议中。

在真正的对等模式下,我们从不参与任何交易。 因为我们不是参与的一方,我们不可能对第三方托管强加支出条件——比如接收方如何以及何时可以使用比特币。

我们的机制对面对面的交流特别有用。 用户可以在不接入互联网的情况下从第三方托管中释放比特币。 通过发送带有唯一代码的短信,或向买家显示二维码,将有可能触发释放。 稍后再详细介绍。

批量生成和签名密钥

创建LocalCryptos帐户时要做的第一件事是生成大量随机密钥并对它们进行签名。 当然,这发生在后台——普通用户不会注意到它。

这些短暂的密钥分为三类,其中两类与BTC托管相关。

生成端到端消息传递密钥

在注册时创建的随机密钥的不相关类别是端到端加密密钥。 这些密钥允许人们在你离线时与你进行加密对话。 LocalCryptos借鉴了流行的前向加密消息应用程序(如Signal) 的这一思想。 你可以在LocalEthereum的原始白皮书中了解更多。

生成钱包地址

当您在非保管的LocalCryptos钱包中生成一个比特币地址时,您还将一个签名版本上传到LocalCryptos。 当网络钱包自我设置时,它会创建并签署数百个比特币地址。

您的私钥的加密副本也会被上传,以允许您从其他设备登录。

同样的过程也发生在我们的其他网络钱包上,包括Ethereum。

这允许其他人与你打开交易和基金托管,即使你离线。 用户从我们这里获取您的一个地址,并根据您的公钥检查签名。 这样做有助于避免复杂的中间人攻击的风险。

生成托管秘钥

托管密钥是比特币代管特有的,因为Ethereum的代管系统是不同的。

托管密钥是32字节的密码,您可以稍后再透露。 生成密码的散列(使用hash160) 并对该散列进行签名。 然后,将散列代码、签名和加密的密码上传到LocalCryptos。

资金托管

为了将BTC置于托管状态,卖方创建一个包含两个输出的比特币交易。 一个输出用于托管的金额,另一个输出是LocalCryptos的可退还费用。

在此之前,卖家需要从LocalCryptos获取一些细节:

  1. 散列的托管密钥代码来自买方、仲裁员和卖方(他们自己的)。
  2. 一个来自买方的签名,他们可以用来验证散列的托管密钥代码。
  3. 来自买方和他们自己的散列公钥。
  4. 来自买方的验证公钥的签名属于买方。
  5. 仲裁员散列的公钥,因此他们可以发送少量费用。

卖方将确认买方的每一个签名都是有效的。 一个不正确的签名意味着黑客试图篡改托管。

托管输出

为买方携带金额的托管输出是以下脚本的P2SH-P2WSH地址:

OP_DUP OP_1 OP_EQUAL
OP_IF
  # Release by seller
  OP_DROP
  <BuyerPubKeyHash>
  <ReleaseCodeFromSellerHash>
OP_ELSE
  OP_DUP OP_2 OP_EQUAL
  OP_IF
    # Release by arbitrator
    OP_DROP
    <BuyerPubKeyHash>
    <ReleaseCodeFromArbitratorHash>
  OP_ELSE
    OP_DUP OP_3 OP_EQUAL
    OP_IF
      # Return by buyer
      OP_DROP
      <SellerPubKeyHash>
      <ReturnCodeFromBuyerHash>
    OP_ELSE
      OP_4 OP_EQUALVERIFY
      # Return by arbitrator
      <SellerPubKeyHash>
      <ReturnCodeFromArbitratorHash>
    OP_ENDIF
  OP_ENDIF
OP_ENDIF
OP_ROT
OP_HASH160
OP_EQUALVERIFY
OP_OVER
OP_HASH160
OP_EQUALVERIFY
OP_CHECKSIG

产生的费用

产生费用的比特币金额约为交易规模的1%。 如果交易成功,LocalCryptos将收取费用。 如果有取消,卖方可以解锁输出要求全额退款。

产生的费用以P2SH-P2WSH地址为脚本:

OP_DUP OP_3 OP_EQUAL
OP_IF
  # Return by buyer
  OP_DROP
  OP_HASH160
  <ReturnCodeFromBuyerHash>
  OP_EQUALVERIFY
  OP_DUP
  OP_HASH160
  <SellerPubKeyHash>
  OP_EQUALVERIFY
  OP_CHECKSIG
OP_ELSE
  OP_DUP OP_4 OP_EQUAL
  OP_IF
    # Return by arbitrator
    OP_DROP
    OP_HASH160
    <ReturnCodeFromArbitratorHash>
    OP_EQUALVERIFY
    OP_DUP
    OP_HASH160
    <SellerPubKeyHash>
    OP_EQUALVERIFY
    OP_CHECKSIG
  OP_ELSE
    # Spend by LocalCryptos
    OP_DUP
    OP_HASH160
    <ArbitratorPubKeyHash>
    OP_EQUALVERIFY
    OP_CHECKSIG
  OP_ENDIF
OP_ENDIF

等待确认

LocalCryptos要求大多数比特币托管至少要有一个确认块。 根据交易所的规模,较大的交易需要最多6个确认。

泄露密码

买方已经拥有解锁托管事务所需的两个输入之一:他们自己的公钥。 唯一缺少的是卖方的秘密“卖方发布”代码。

同样地,卖方离打开托管只有一个输入。 如果他们掌握了买家的秘密“返还买家”代码,他们就能收回托管的金额。

仲裁员持有“releaseby仲裁员”和“returnby仲裁员”托管密钥的密码。 如果发生付款争议,仲裁员可以通过披露其中一个秘密来解决。

这是无保管式托管制度的症结所在。 散列脚本包括每个密码的散列,但不包括真正的代码。

使用密码

要使用托管输出,接收者需要编译一个签名,包含以下内容:

前两项与花费的P2PKH输入相同,后两项对于LocalCryptos是惟一的。

“活动”字节将告诉脚本要检查哪个散列。 在标准交易中,买方将使用“由卖方发布”的代码(0x01)。 如果第一项是0x01,那么脚本将期望得到买方的公钥和卖方的发行代码。

有四个代管行动,代表了所有的方案代管:

活动 字节 期望的代码 期望的PubKey
释放由卖方 0x01 卖方 买方
释放由仲裁员 0x02 仲裁员 买方
返回由买方决定 0x03 买方 卖方
返回由仲裁员决定 0x04 仲裁员 卖方

收回费用输出

在取消托管的情况下,LocalCryptos不收取任何费用。 我们只收取比特币买家的费用。

通过返回托管代码,上面的签名也与费用输出兼容。 卖方可以按照他们使用被召回的UTXO托管协议的方式来使用费用输出。

当你花钱的时候安顿下来

在LocalCryptos的比特币托管中单击“Release”不会更改区块链上的任何内容。 它允许接收方使用托管的硬币(即解锁UTXO)。

接收方可以选择立即使用这些硬币,也可以选择等待。 在用户界面中,一个第三方UTXO将出现在您的常规地址旁边的web钱包中。

在花费硬币后,托管的完成便永久蚀刻到区块链里。

在没有互联网连接的情况下释放

买方需要的只是卖方的密码来要求托管。

我们可以添加一个方法,让卖家在没有互联网连接的情况下显示他们的代码。 代码太长,不能写在纸上,但它是一个完美的长度存储在你的手机或二维码里。

LocalCryptos将添加两种新的方式来显示代码:

1. 通过向我们的一个电话号码发送短信来显示密码。我们的服务器可以计算代码的散列来识别它属于哪个交易,然后将代码转发给买家。

2. 向买家出示二维码。 买家不需要通过互联网验证代码; 他们只需要一个软件,可以计算一个哈希。 这种方法可以在没有一个稳定的互联网连接时仍然能面对面交流。 在委内瑞拉,这将是有用的,因为国家停电是一个常见的事件。

我们今天正在研究第一种选择。 第二个选项将在我们发布LocalCryptos移动应用程序时可用。

这有多安全?

即使是最好的超级计算机也无法破坏使用单一哈希的标准P2PKH地址。 哈希160的键空间是160位。 我们使用两个hash160:一个用于P2PKH部分,另一个用于散列密码。 这就为外部攻击者提供了320位的密钥空间。 (数学计算比这更微妙,但你明白我的意思。)

LocalCryptos的比特币托管地址——无论出于何种目的——都不可能被破解。

这个要多少钱?

我们已经通过升级到隔离见证(Segregated Witness)来降低网络费用。 然而,比特币交易的成本往往高于Ethereum。

比特币托管的成本取决于网络的拥挤程度。 对于低于10美元的小型交易,我们建议选择另一种加密。

这是最终版本吗?

这可能不是LocalCryptos的非保管式比特币托管的最终版本。 在未来,我们计划优化系统的成本和速度。