硬核 | 怎样使用 Substrate 做一个能安全支持百万地址的热钱包?

用于 runtime 开发的 Substrate 和 FRAME 体系界说了一组强壮的原语功用,用于构建区块链根底架构。将两者一起运用,为处理现有问题创造了新颖的办法。本文将描述一个实践应用程序,其间 Substrate 的函数用于实现多地址热钱包。

热钱包通常意味着将开销密钥保存在在线设备上,以便能够方便地创建和播送买卖,但风险通常较高。本文将探讨一些 Substrate 的账户笼统 —— 多签名账户、署理账户和衍生账户 —— 如何让咱们能构建一个能够安全支撑数百万个地址的热钱包。

假如您需求为多个用户账户持有代币,但又想为每个客户供给自己的存款地址,那么这样的钱包将十分有用。简略的处理方案是经过生成新的密钥对为每个客户生成一个新的存款地址。可是快速处理一切这些密钥对并不简略。假如您有不计其数的用户怎么办?运用 Substrate 的账户笼统,咱们能够构建一个可扩展性和安全性更高的处理方案。

来历和账户 ID

在开端构建热钱包之前,咱们需求奠定它将要运用的根底。当用户与区块链进行交互时,他们正在调用某些函数。这些 “可调度(dispatchable)” 函数的调集构成了区块链的界面。

因为可调度函数是从外部调用的,因而区块链或许首要关怀的是谁真正调用了该函数。首要,一个函数需求查看调用方是否有权履行该函数。其次,链或许需求确切地知道谁调用了该函数以更新有关调用者的一些信息。假如调用者是一个账户,则链或许需求更新该账户的余额,例如扣除买卖费用。

您或许会想,“假如调用者是账户,那意味着什么?” Substrate 中的函数自身不是来自帐户,而是来自来历(origins)。例如,Polkadot 的治理体系具有一系列特别来历,这些特别来历具有特权,例如分配国库资金或吊销 Slash。假如您运用 Substrate 设计自己的区块链,则能够创建自己的自界说来历。可是,本文要记住的一点是,账户只是 Substrate 来历的一种变体。您能够想象成 Substrate 告知可调度函数,“此调度的来历是一个账户。”

已然咱们现已实现了笼统的榜首个腾跃,咱们需求一种办法来告知函数来历是指哪个账户。假如您运用过任何区块链,则或许会习惯于运用一个账户 ID 作为与私钥相对应的公钥。这没问题,这一点也能够在 Substrate 中运用。从这个意义上说,一个账户由公钥标识,并由相应的私钥授权。

Substrate 支撑更多笼统。账户 ID 能够是任何 32 个字节的数字。[1]能够是与私钥相对应的公钥,但不是必须的。它只需求某种授权办法。就像在其间一样,必须有某种共同的办法来生成此帐户标识号,以便 Substrate 能够完结上述开头的语句:“此调度的来历是由该编号标识的账户。” [2]

哈希函数

哈希函数一直在区块链中呈现。区块实践上是经过其哈希值链接在一起的。可是咱们将运用哈希函数的特点来达到别的两个意图:生成账户 ID 和识别函数调用。

哈希函数会接受一些恣意巨细的输入,并将其映射到固定巨细的输出(例如 32 个字节)。可是,它不仅将数据映射到任何 32 字节的数字,而是应该确认性地将仅有数据映射到一个仅有的数字。碰巧的是,32 个字节能够捕获天文数字量级的 item。[3]

例如,咱们能够获取有关链的一些信息,例如 “polkadot-treasury”,并运用哈希函数将其转换为账户 ID (32 字节)。或许,咱们能够获取有关某些买卖的信息,例如 “将 10 个单位搬运到账户 123…”,并相信哈希是该信息的仅有图像。

多签账户

有了这些,咱们就能够开端构建热钱包的榜首部分:多重签名(multisig)账户。因为总体比较粗笨,多重签名账户或许看起来不像是热门钱包的一部分,可是此账户将作为其余组件的安全根底,而且刚刚所说的粗笨不会阻碍日常运用。

一些区块链运用加密多重签名,其间多个密钥持有者在链上提交买卖之前,先在链外签署了单个买卖。Substrate 的 FRAME 顺便的多重签名体系以另一种办法作业:它依据构成多重签名的各个账户以及从生成的账户中分发所需的必要阈值来生成账户 ID。Substrate 向一切这些信息添加一个特别的多重签名前缀,并对其进行哈希处理以获取一个 32 字节的输出,该输出将用作多重签名账户 ID。请注意,此账户 ID 没有与其相关的私钥。

为了从该新帐户 ID 授权买卖,多签的成员均运用其期望多签帐户进行的函数调用在链上提交买卖。可是,每个人都提交函数调用效率不高;它或许很大,而且区块空间是稀缺的(因而很昂贵)。哈希函数再次派上用场:只需一个账户需求提交实践的函数调用;其他人只提交哈希。他们只用说:“咱们赞同经过多签账户运用此哈希调用函数”,而无需从头提交函数。

这个多重签名自身太笨拙,无法用作热钱包,因为它需求多个密钥持有者提交买卖才干使其正常作业。可是它是高度安全的,能够将它作为基本账户,而咱们能够在不牺牲其安全性的情况下将其转变为热钱包。

署理账户

署理帐户允许多签地址将开销权限委派给另一个账户,该账户将用作热钱包,一起仍保持多签的安全。咱们将设置一次性延时署理来办理开销,并设置另一个(或多个)即时署理来办理此多签账户的安全性。

署理账户将一个账户的特权授予另一个账户,以代表该账户进行函数调用。这些特权能够是特定的,例如 “仅限与典当相关的买卖”,或广泛的,例如 “不触及搬运资金的一切买卖”,甚至是完好的特权,如 “任何买卖”。

创建署理只需求从要署理的账户进行一次买卖,并说明哪个其他账户是其署理及其特权。署理关系到位后,署理账户就能够为署理账户进行买卖,本质上便是告知链:“我是该账户的署理,我具有这些特权,而且我想代表署理账户。” 链的逻辑将验证署理的确具有正确的特权,并运用署理账户的来历差遣该功用。

添加时间延迟会添加一层安全性。想象一下 600 个区块的时间延迟(在 Polkadot 中为一小时)。署理账户仍会提交买卖,说它是具有某些特权的署理,但只会宣告它要进行的函数调用的哈希值。署理账户的一切者能够请求实践的函数调用并进行审查。假如一切者不赞同,他们能够经过在延迟时间到期之前提交另一个买卖来拒绝函数调用。在时间延迟之后,署理能够提交与布告相对应的实践函数调用,然后由 Substrate 调度。[4]

关于咱们的用例,多签密钥持有者将进行买卖以将另一个账户设置为具有彻底特权的延时署理,例如包含余额搬运在内。也许此署理账户将存在于可自动进行买卖的在线服务器上。每逢进行买卖时,它都必须先宣告哈希,然后将实践的函数调用发送给其他帐户持有人(为简略起见,咱们将此其他帐户持有人视为多签的成员),他们能够验证该函数调用是否为非歹意的。假如是歹意的,多签能够及时进行买卖以拒绝该调用,而且出于谨慎考虑,确认署理账户已被盗用并将其删去。

这样装备的确行得通,可是咱们依然能够让它变得更方便运用。仅运用一个署理,咱们或许需求很长的时间延迟,因为和谐满足多的多重签名密钥持有人以进行拒绝买卖或许会在短时间内比较困难。可是一个帐户能够有多个具有不同特权的署理帐户。要处理此问题,请将每个多签密钥持有者设置为具有非转账特权的署理,尤其是具有拒绝来自延时署理的告诉的特权。

让咱们简要介绍一下此装备。在中心,咱们有一个多签账户。该账户没有私钥,可是有两种办法能够操控它:运用延时署理账户或搜集满足的成员账户签名者。多签的每个成员还具有拒绝来自彻底特权署理的买卖的才能,可是假如没有其他成员参加进行多签买卖,则无法进行余额转账。

它自己便是一个功用完全的热钱包,只需删去署理并设置一个新的热钱包即可更改热键(具有彻底特权的署理帐户),而无需更改其地址(多重签名帐户)。可是咱们最初的问题陈述要求不计其数的用户运用仅有的存款地址,到目前为止,咱们只需一个用户。

衍生账户

到目前为止,咱们现已运用多种办法拜访一个多重签名账户。现在,咱们将运用一个帐户拜访许多账户。

Substrate 中的每个账户都有一个能够拜访的衍生帐户树。为了获得账户 ID,Substrate 理所当然地运用来哈希算法。经过用所需的索引和派生前缀对建议调用的帐户的账户 ID 进行哈希处理,Substrate 创建了一个新的账户 ID。例如,发送方供给一个函数调用和一个索引,说:“我想从具有此索引的派生账户中调度此函数。”

你或许现已猜到后边会产生什么了。钱包一切者能够为其每个用户分配一个索引,并供给派生账户 ID 作为该用户的存款地址。为了拜访资金,署理地址将发出买卖以从多重签名帐户的派生地址搬运资金。

具体而言,索引约束为 16 位或 65,536 个派生帐户,可是也能够嵌套。也便是说,每个衍出产帐户能够具有自己的 65,536 个衍出产帐户集,依此类推。树的第二层将具有超越 40 亿个账户。

全貌

最终让咱们把这些知识用起来。想象一下,索引为 11 的用户向您付款,您有一些 “储蓄账户” 要存入资金。整个买卖看起来像是:“我是多签账户的署理人,我想将资金从多签的衍生账户(索引为 11) 搬运到储蓄账户。”

假定对监管者来说一切正常,则延迟时间将到期,而且署理能够播送完好的买卖。假如多重签名成员以为热键需求更改,他们能够简略地生成一个新密钥并将旧密钥作为署理删去,而不会影响多重签名或其任何派生地址。

硬核 | 怎样使用 Substrate 做一个能安全支持百万地址的热钱包?

上图显现了咱们已设置的钱包的示意图:多重签名(MS)由一组 n 个密钥(记为 k)操控,并将时间延迟署理(H)设置为热键。它几乎能够从多签中导出无限的地址(d 的调集)。

咱们甚至能够进一步优化此作业流程。Substrate 还供给了发送一批函数调用的函数。假如用户定期在其衍生帐户中进行存款和提款,你能够在一批转账中将其全部发送。

Substrate 的链上帐户笼统供给了办理账户的强壮办法。经过削减所需的实践密钥数量并依据正式规矩而不是私钥拜访账户,您能够操作不计其数个账户,而不用处理存储相等数量的签名密钥的约束。本文仅重视构建热钱包的一个示例,可是一切笼统都是孤立的,能够组成更高档的应用程序。

注释:

  1. 不用非得是 32 个字节。您能够随心所欲地构建 runtime,但我不期望本文超出了必要范围。↩︎

  2. 快速解说一下 “unique” 一词,从严厉的意义上讲,我在这里的意思比一般字典中的界说更严厉。一个账户是仅有的,并不是说它只能有一个表明,而是一切表明(或一系列表明)都可证明为相等的。或许存在无限数量的办法来生成一个特定的数字(账户),可是只需一切这些办法都的确生成相同的帐户,那么该账户就能够视为仅有的。具体解说其间的数学原理会杂乱到让你头大,可是咱们将生成账户 ID 并将它们在函数之间传递,这里的关键是无论咱们有多少个函数串在一起(串联)以到达某个帐户 ID,它在充当调度源的方面表现为相同的账户 ID。↩︎

  3. 假如您有兴趣了解的话,32 个字节最多可包容 1.15x10 ^ 77。到可调查宇宙边际的距离为 457 亿光年,即 4.32x10 ^ 23 公里或 4.32x10 ^ 29 毫米。假如咱们咱们把它想作是一张平面的光盘,则其面积为 5.87x10 ^ 59 平方毫米。咱们依然相差 10 ^ 18 或十亿平方。因而,两个不同的哈希输入具有相同输出的时机就像两个项目都落在可调查的宇宙中的同一平方毫米上,然后将其分解为 10 亿乘以 10 亿的网格,然后又都落在了相同的正方形上。这些正方形是 1 皮米(picometer)宽。作为参阅,氦原子的直径为 62 皮米。↩︎

  4. 实践上,只需署理发出告诉,任何账户都能够提交调用,可是出于实用主义的考虑,假定咱们的热钱包仅运用同一账户进行告诉和提交。↩︎

视野开拓

有效性是由其有用性来评判的-《价格理论及其应用》

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注