基于区块链的智能锁设计与实现一、优势基于区块链技术实现的智能锁应用,可实现常规厂商难以企及的 高安全性,同时亦不损失灵活性。该论断基于以下几点:•服务提供者即区块链;•区块链数据的可信性(公开透明、不可篡改);•开放协议,开源代码;•用户不被特定厂商所 绑架。二、基本原理2.1 功能逻辑划分智能锁根据功能分为两部分:•门锁。硬件,内置程序,该程序需要联网读取区块链数据,以验证钥匙的权限,从而决定是否开锁;•钥匙。软件,区块链钱包应用程序负责其 创建、存储、使用 和 转让 等业务操作。 开锁 操作需要持有者向锁证明其拥有锁的控制权,锁通过访问区块链上数据来执行验证。钱包内的钥匙可以在不同用户的钱包内进行转让流通,即交付给下一个使用者。这可以广泛应用于共享经济,如租房、租车等。2.2 开锁验证流程锁在区块链上查找包含有自身ID 标识的那个UTXO(未花费的交易输出),通过验证UTXO 的控制权以确认是否有锁的控制权(该UTXO 的控制权即锁的控制权)。具体过程是:1:取出控制者的公钥(或地址),然后向试图开锁者发送一个要求,要求其对自己生成的一个随机数用私钥签名,并发回给自己,2:如果签名正确,那么说明对方持有正确的钥匙,即验证通过,可以开锁。3:钥匙可以使用比特币本身拥有的 多重签名机制,如2/3签名,表示3把钥匙有任意2把同时通过验证(需要配合 不同钥匙的有效期),即可以开锁。这特别适合用于 共享经济。2.3 应用场景示例在租房应用场景中,我们可以为锁配备3把不同的钥匙,应用2/3签名,并分别分配给3方各自持有。具体如下:•中介公司持有1把钥匙,开锁操作单次有效;•租户持有1把钥匙,开锁操作单次有效;•房东持有1把钥匙,开锁操作永久有效(在全部3方持有者没有任何变更的情况下),即:相当于这把钥匙一直插在钥匙孔里。由于是2/3签名,再有任一另一把钥匙插进来,即可开锁。这样以来,租户和中介公司任意一方都可以使用自己的钥匙开锁,但房东不行,他必须再找个人帮他开锁。这个设置乍一看似乎不合理,但仔细分析一下:•房东是个人行为,通常不受约束,如果其可以随意开锁进门,这对租房者不利;•中介公司持有的钥匙在使用时通常比较谨慎,因为其需要维护良好的信用和口碑。因此中介公司不会随意开锁去危害租房者的利益,即使有个别极端情况,概率上是比房东更受控的;•而租房者是使用者,需要随时可以开锁,不应该受到约束。因此上述设置是合理的。但房东也应该有开门的需求,那么可以找中介公司和租户任一方协助开门,这同时保证了其它两方的知情权;而房东也需要在必要的时候能够 维权,那么我们也正好兼容此需求!在上述设置方案中,房东可以随时拔下钥匙(即:通知锁让本钥匙失效),此时租户和中介公司单方面都无法开锁,他们必须再找一方协商解决问题。不过房东通常没有理由这样做,除非利益受到损害。仅能拔下钥匙的维权方式设计,也避免了维权过猛而造成的伤害。在房东拔下钥匙后,如果仍希望避免租户和中介公司串通单方面开锁,可以在锁程序中给房东的钥匙设置投票权超过1的权重,这样租户和中介的权重之和低于2,仍无法开锁,必须经过房东的同意并重新插入钥匙。即:房东拔下钥匙可以迫使租户和中介公司积极应对房东的维权要求。2.4 钥匙的转让交接这个过程非常简单,与比特币的支付操作无异。只不过如果是多签名的话,也需要多方签署这笔交易。支付操作完成后,这个携带锁ID 的UTXO 将归比特币接收地址的控制者所有,控制者的数量也可以变更,各方的投票权重可以由植入UTXO 内的协议控制。UTXO 控制权的变更意味着锁的控制权变更,即等同于钥匙的变更交接:钥匙进入了新的使用者的钱包。使用者的变更可以仅仅是租户,也可以是其它任意各方使用者,这取决于(或决定着)UTXO 的收款地址如何构造。三、技术实现需要三个参与方的程序/数据交互协作。3.1 协议化UTXO需要将锁的ID 植入到 UTXO,这需要创建协议数据结构并完成一个支付操作,此时该协议化的UTXO 便存在于区块链上了。例如,这是一个正常的交易(transaction)数据结构:{hash:3b06b1e9d70217d5e02644703fe79f54355b0ea05cd535787f5a6c627f1c,ver:1,vin_sz:2,vout_sz:1,lock_time:0,size:404,in:[{prev_out:{hash:022e05bdfa2e148bc1882cb7a81506b8316fee6957b11625126d075a8cf8791b,n:0},Sig: 304402203c1db72394263dd50070b91bb1da9125c591f15772dfc628f41447dabb7798a10220302dc6e7e8c81e24da9a99d5ac7233b90156a410051a50bb29d55aabbf0ff24d0102b8c918bd169a5e669cc149549f822dd5f2c50872eb83172a1c69172277fe378f},{// 另一个输入,省略…}],out:[{value:12.51603279PubKey:OP_DUPOP_HASH160 69e02e18b5705a05dd6b283d517716c894b3d42eOP_EQUALVERIFY OP_CHECKSIG}]}应该在PubKey 字段位置插入协议信息。协议内容格式 可初步定义为如下Uri 格式:lock://id/e10exxxx.../sig/2*3/pubs/62e*73a*84b/addrs/1ac*2bd*2ce/weights/1.2*0.9*0.9/povs/0*1*1将该Uri + OP_DROP 插入到PubKey 字段值的OP_DUP 前面,即可完成植入。其中:lock是协议的识别标识;id表示锁的ID;sig表示多签名规则;pubs表示多签验证需要使用的公钥信息,这里紧填开头最短的部分,用于辨识与weights 权重设置对应的公钥;addrs表示多签验证需要使用的公钥hash 地址信息(与pubs 二选一,其中的“*”是分隔符,将多个地址或者公钥分开);weights表示每个公钥的投票权重;povs表示组合有效期,0为永久有效,1为单次有效。3.2 门锁端程序每个锁硬件需要能够在重置时生成 ID(确切地说,是符合高阶最小熵分布的安全随机数),并能够在特定操作下(如按住某按键)允许查询该 ID,以备创建协议UTXO 和钥匙时使用。需要为锁安装程序,该程序需要随时联网查询其ID 对应的 UTXO,进而验证该UTXO 的控制权以确认是否拥有钥匙。但需要注意一点:该UTXO必须与初始化时的UTXO处于同一条支付流转链上,不可以是任意 UTXO,以防恶意破坏。在操作上,应遵循如下逻辑:锁程序应当存储初始化时的UTXO 的txid(区块链账本上记录的一条交易的 id),若发现该UTXO 已经被支付,则应当查找支付目的地的UTXO 并更新锁内存储的txid,而忽略其它任何包含本ID 的UTXO(它们可能是恶意混淆,当然自己也可以故意混淆以防止追踪)。有txid 的跟踪,可以 不要求锁ID必须唯一。3.3 用户端程序用户端程序,即:区块链钱包(后文简称钱包)。用于钥匙的 创建、存储、使用 和 转让 等业务操作。其中存储和转让操作与比特币的支付操作无异。关于创建和使用开锁操作见后文。3.4 初始化门锁的初始化,即创建一个协议化的 UTXO,同时也是钥匙的创建过程。分为以下步骤:1. 获得物理锁的控制权。很重要。可防止锁被非法用户恶意操作;2. 重置并生成新的 ID。在特定物理操作的前提下(如长按reset 按钮);3. 钱包读取门锁 ID。读取方式可通过 二维码 或 无须配对的 低功耗蓝牙BLE技术来实现;4. 钱包根据即将分配钥匙的各方所提供的公钥,生成UTXO 的目标地址;5. 钱包创建协议数据(见3.1节),打包并发送交易。至此协议化UTXO 已生成;6. 将该UTXO 的txid 回传到门锁端应用程序,存储以备开锁验证使用。3.5 开锁步骤前提假设:锁完全受控于主人,锁的 验证程序 是开源且可信的。这意味着:锁不会恶意开锁或不开锁,不会泄露用户数据和隐私信息,也不会有严重的 bug 导致执行非预期的逻辑。不过即便如此,我们仍然 不应向锁提供私钥,这是底线。下面分两种情况来描述开锁操作的具体步骤。- 单签名钥匙。如果协议化UTXO 的收款地址是一个公钥或公钥hash,那么它的钥匙就是单签名钥匙(也可以说这把锁是单钥匙孔的锁),这需要在初始化时与生成的协议保持一致。开锁步骤如下:①用户发出开锁申请。可以是按下一个锁的硬件按钮;②锁联网连接区块链节点查询指定txid(见3.2节)的 UTXO,检查其内置的协议是否包含自身 ID,并检查该UTXO 是否已经被花费。若未被花费,进行下一步;否则一直向后追溯到最新没有被花费的 UTXO,并用其txid覆盖锁内之前存储的txid,然后进行下一步;③锁生成一个随机数并通过BLE 蓝牙广播一条报文,报文中同时携带锁ID 的前几位以示区别。该报文可简单表示如下:{id:d62a9e,random:34576578901823912}④钱包收到该报文,用控制该UTXO 的私钥签名该随机数,并回复报文(其中sig 表示对随机数的签名,pub 表示公钥):{id:d62a9e,sig:304402203c1db72394263dd50070b91bb1da9125c591f15772dfc628f41447dabb7798a10220302dc6e7e8c81e24da9a99d5ac7233b90156a410051a50bb29d55aabbf0ff24d01,pub:02b8c918bd169a5e669cc149549f822dd5f2c50872eb83172a1c69172277fe378f}⑤锁收到报文,先判断 pub 是否与UTXO 中的公钥或公钥hash 匹配,若匹配,则用公钥解密sig 数据,看结果是否与自己发出去的随机数random 相等,相等表示验证通过(即:插入了正确的钥匙);⑥若上一步验证通过,则驱动马达执行物理开锁操作,完成开锁;否则广播回复报文钥匙不匹配。- 多签名钥匙。协议化UTXO 的收款地址是多个公钥或公钥hash。由于多签名钥匙的开锁组合有效期分为单次有效,和永久有效。这里定义 单次有效 为 从该钥匙请求开锁到实际物理开锁的整个时间段内(开锁即清除状态)。永久有效 是指 从当前UTXO 产生到被花费的整个时间段内(更新txid 即清除状态)。开锁步骤如下:①用户发出开锁申请。可以是按下一个锁的硬件按钮;②锁联网连接区块链节点查询指定txid(见3.2节)的 UTXO,检查其内置的协议是否包含自身 ID,并检查该UTXO 是否已经被花费。若未被花费,进行下一步;否则一直向后追溯到最新没有被花费的 UTXO,并用其txid覆盖锁内之前存储的txid,然后进行下一步;③锁生成一个随机数并通过BLE 蓝牙广播一条报文,报文中同时携带锁ID 的前几位以示区别。该报文可简单表示如下:{id:d62a9e,random:34576578901823912}④钱包收到该报文,用 对该UTXO 有一部分控制权 的私钥签名该随机数,并回复报文(其中sig 表示对随机数的签名,pub 表示公钥, 表示多签名收款脚本):{id:d62a9e,sig:304402203c1db72394263dd50070b91bb1da9125c591f15772dfc628f41447dabb7798a10220302dc6e7e8c81e24da9a99d5ac7233b90156a410051a50bb29d55aabbf0ff24d01,pub:02b8c918bd169a5e669cc149549f822dd5f2c50872eb83172a1c69172277f