地址格式
基于Substrate的链使用的地址格式是SS58。SS58是对比特币中的Base-58-check的修改,并做了一些小改动。值得注意的是,该格式包含一个地址类型前缀,用于标识属于特定网络的地址。
例如:
- 波卡地址始终以数字1开头。
- Kusama地址始终以大写字母开头,如C、D、F、G、H、J。
- 通用的Substrate地址始终以数字5开头。
这些前缀以及地址验证方法,都嵌入在Substrate SS58格式中。永远不要使用正则表达式进行地址验证。
关键要理解,不同网络的格式只是由地址生成工具生成的私钥-公钥对中的同一公钥的其他表示形式。因此,只要格式是正确转换的,那么基于Substrate的链上的地址是兼容的。
在Runtime28中,默认的地址格式(详情请参见:
https://wiki.polkadot.network/docs/learn-accounts##address-format)为【MultiAddress】类型。
这个【enum】是链上账户的多格式地址包装器,用于描述波卡的默认地址格式,以表示许多不同的地址类型。其中包括20字节、32字节和任意原始字节变体。它还增强了原始【indices】(详情请参见:
https://wiki.polkadot.network/docs/learn-accounts#indices)查找功能。
注:
许多钱包允许你在不同格式之间进行转换。也有独立的工具;你可以在地址转换工具(详情请参见:
https://wiki.polkadot.network/docs/learn-account-advanced#address-conversion-tools)部分找到它们。
派生路径
如果你想在网络上使用同一种子创建和管理多个账户,你可以使用派生路径。我们可以将派生账户视为使用原始助记词种子创建的根账户的子账户。许多波卡密钥生成工具支持硬派生和软派生。例如,如果你打算创建一个要在波卡链上使用的账户,可以在助记词后面加上//来派生一个硬派生的子账户。
或者在助记词后面加上/,来派生一个软派生的子账户
如果你想使用同一种子在波卡链上创建另一个账户,可以更改上述字符串末尾的数字。例如,【/1】、【/2】和【/3】将会创建不同的派生账户。
你可以在派生路径中使用任意字母或数字,只要你认为有意义即可;它们不必遵循任何特定的模式。你还可以在路径中组合多个派生。例如,【//bill//account//1】和【//john/polkadot/initial】都是有效的。
要重新创建一个派生账户,你必须知道种子和派生路径,因此你应该使用一个明确定义的顺序(例如//0、//1、//2...)或确保写下使用的每个派生路径。
注:
只有知道派生路径,才能生成派生账户。
还有一种派生类型叫做密码派生。在波卡上,你可以在助记词后使用///来派生密码密钥账户
在这种类型的派生中,如果助记词泄漏,没有初始密码就无法派生账户。实际上,对于软派生和硬派生的账户,如果有人知道助记词和派生路径,他们就能够访问你的账户。对于密码派生的账户,密码应用于派生路径。你可以知道助记词和派生路径,但如果没有密码,则无法访问该账户。
用数学术语来说,如果我们有一个书面派生路径【written derivation path】和密码【password】,就可以计算出真实的派生路径【real derivation path】,即f(书面派生路径,密码【written derivation path,password】),其中f是一个函数。
然后,我们可以使用f(种子,真实派生路径【seed,real derivation path】)来计算账户密钥对【account key pair】。与可以混合使用的硬派生和软派生不同,每次派生只应指定一个密码。
注:
密码派生账户的安全性取决于所选的密码的安全性。
软派生vs硬派生
软派生允许某人在知道派生账户私钥的情况下, "逆向"找出初始账户的私钥。此外,还可以确定由同一种子生成的不同账户与该种子相关联。硬派生路径则不允许这两项操作——即使你知道派生私钥,也无法计算出根地址的私钥,也无法证明第一个账户与第二个账户相关联。鉴于所有派生账户的私钥都是完全安全的,因此这些派生方法都有其用武之地。除非你有软派生的特定需要,否则建议使用硬派生路径生成账户。
有关派生路径格式的详细信息和示例,请参阅Subkey文档(详情请参见:https://docs.substrate.io/reference/command-line-tools/subkey/)。Polkadot-JS应用程序和插件以及Parity签名器(Parity Signer)支持使用与Subkey相同的语法进行自定义派生路径。
有些钱包会在生成的助记词末尾自动添加派生路径。这将为不同的路径生成单独的种子,允许使用相同的助记词进行不同路径的签名,例如【//polkadot】和【//kusama】。尽管你可能正确保存了助记词,但只有当两个钱包使用相同的派生路径时,在另一个钱包中使用助记词才会生成相同的地址。
Polkadot和Kusama都在BIP44registry(详情请参见:
https://github.com/satoshilabs/slips/blob/master/slip-0044.md)登记了路径。
注意:
要获得某个地址的密钥,你必须知道其父节点私钥和派生路径。只有当你熟悉了这一主题的知识后,才能使用自定义派生路径。
有人好奇:前缀是如何工作的?
SS58registry(详情请参见:
https://github.com/paritytech/ss58-registry/blob/main/ss58-registry.json)指出:
- 波卡具有地址类型【00000000b】(十进制为【0】)。
- Kusama(波卡金丝雀网络)具有地址类型【00000010b】(十进制为【2】)。
- 通用Substrate的地址类型是【00101010b】(十进制为【42】)。
由于【Base58-check】字母表中没有数字0,因此最小值确实是1。因此,【00000000b】在Base58-check中是1。如果我们尝试解码类似【1FRMM8PEiWXYax7rpS6X4XZX1aAAxSWx1CrKTyrVYhV24fg】的波卡地址,则结果为
【000aff6865635ae11013a83835c019d44ec3f865145943f487ae82a8e7bed3a66b29d7】。第一个字节为【00】,二进制为【00000000】,十进制为【0】,因此符合波卡的地址类型。
让我们来看一下Substrate地址。如果我们解码【5CK8D1sKNwF473wbuBP6NuhQfPaWUetNsWUNAAzVwTfxqjfr】,我们会得到
【2a0aff6865635ae11013a83835c019d44ec3f865145943f487ae82a8e7bed3a66b77e5】。第一个字节为【2a】,从十六进制转换成十进制(详情请参见:
https://www.rapidtables.com/convert/number/hex-to-decimal.html)后为【42】。42在二进制中是【00101010】,正如SS58文件中所述。
最后,让我们看看Kusama地址。解码【CpjsLDC1JFyrhm3ftC9Gs4QoyrkHKhZKtK7YqGTRFtTafgp】会得到【020aff6865635ae11013a83835c019d44ec3f865145943f487ae82a8e7bed3a66b0985】,并且第一个字节为【02】,就像指定的一样。
如果我们尝试以完全不同的字母开头的Kusama地址,(例如【J4iggBtsWsb61RemU2TDWDXTNHqHNfBSAkGvVZBtn1AJV1a】),我们仍然会得到【02】作为第一个字节:
【02f2d606a67f58fa0b3ad2b556195a0ef905676efd4e3ec62f8fa1b8461355f1142509】。有些地址始终具有相同的前缀,而像Kusama这样的地址则可能变化很大,但这只是Base58-check编码的一个怪现象。
系统账户
顾名思义,系统账户由系统使用。例如,它们用于国库、众贷和提名池。从Runtime的角度来看,这些账户与链上的任何其他账户一样。这些特殊的系统账户只是公钥,私钥是未知的(也无法获取)。因此,只有该模块(pallet)本身才能与此账户进行交互。这些账户永远不会发出已签名的外源extrinsics(详情请参见:
https://wiki.polkadot.network/docs/learn-extrinsics),因为它们没有私钥。
注:
你可以在Subscan(详情请参见:
https://polkadot.subscan.io/account_list?role=module)上查看系统账户。
让我们来看看系统账户是如何在幕后生成的。例如,要生成国库账户,将字符串“modl”和“py/trsry”的原始字节组合起来创建账户ID(AccountID)。有关更多信息,请查看Substrate StackExchange上有关国库账户(详情请参见:
https://substrate.stackexchange.com/questions/536/how-do-treasury-accounts-compare-to-end-user-accounts-in-frame)的文章。
同样,在生成众贷账户时,将字符串“modl”和“py/cfund”的原始字节以及基金指数组合起来创建账户ID(AccountID)。类似的逻辑也适用于提名池和平行链账户。
可移植性
上述信息为我们带来可移植性:在多个钱包使用助记词或种子短语的能力。可移植性取决于几个因素:
- 派生路径
- 助记词格式
- 种子派生
- 签名方案
要在多个钱包中使用完全相同的助记符,请确保它们采用兼容的方法生成密钥和签署信息。如果你仍在寻找易理解的文档,请联系项目维护者。
Ed25519密钥与BIP39的兼容性有限,详情请参见:
https://github.com/paritytech/substrate-bip39
BIP44Registry,详情请参见:
https://github.com/satoshilabs/slips/blob/master/slip-0044.md
基于Khovratovich的Ed25519和BIP32,详情请参见:
https://github.com/LedgerHQ/orakolo/blob/master/papers/Ed25519_BIP Final.pdf
Sr25519已经计划了。