EOS源码分析(4)钱包

钱包是区块链中一个很重要的概念。顾名思义,说到钱包的时候,我们一定会想到它是用来存钱的,但是数字化的钱包和现实社会的钱包还是有一些区别的。现实世界的钱包中真的放着法币,而数字化钱包存放的是钥匙,这把钥匙可以打开存放你余额的保险箱。
我们拿支付宝钱包做一个例子,支付宝钱包这个应用中也没有真实的钱,只有很多个账号和密码,每一对账号和密码都能打开一个保险箱,这些保险箱统一寄存在阿里服务器上。
区块链钱包也和支付宝钱包类似,里面没有真实的货币,而是存储了很多私钥,每一把钥匙都对应着一个数字货币的保险箱,这些保险箱则是保存在区块链上。这里的**就等同于支付宝中的一对账号和密码。这个私钥有以下两点作用:

1. 生成公钥,从而生成交易地址(类似于你的支付二维码)
2. 生成签名,从而签署一笔交易(类似于你的支付密码)

有了以上这两个功能后,你就可以与任何人进行货币的交易了。

EOS 钱包中也保存着**,但EOS钱包和其他区块链钱包也存在着一些差异,主要差异在于EOS 中的**主要是用来生成签名的,它并不用来生成交易地址。也就是说上述私钥中的两点功能,EOS**主要用来支持第二点功能。那如果缺少了第一点功能,别人如何向你转账呢? EOS 的解决办法是引入了账号的概念,账号可以是2位到32位的任意字符串,从而方便用户记忆,用户之间的转账是通过账号来进行操作的。EOS团队认为使用公钥作为交易地址对用户来说太不友好了,没人能够记得一长串无意义的字符串,相比而言,人们更习惯以字符串名称作为账号来使用,因此,EOS引入了账号系统,每个账号都对应的**,主要用来进行签名处理。

接下来,我们将具体了解下EOS系统中钱包所提供的主要接口及其具体的实现。
# 钱包工具
钱包的主要功能就是存储私钥,从而在生成交易的时候可以进行签名。它一般是一个运行在你本地机器的程序。
在EOS系统中,钱包功能是以插件的方式提供的,这使得它可以很容易的集成在EOS节点中运行,也可以作为一个独立的程序运行;

- 集成在EOS节点中
在eosd 所引用的config.ini 文件中加入钱包支持:`plugin = eosio::wallet_api_plugin`, 增加以上配置后,节点就支持钱包接口调用了
- 独立的程序运行
钱包应用的路径为:`path-to-eos/build/programs/eos-walletd`,直接运行此程序即可

## 钱包所支持的命令
`eos-walleted`是一个后台程序,它不直接支持命令行参数,但它支持RPC调用,你可以通过`eosc` 程序与其进行交互,此程序的路径为:`eos/build/programs/eosc`。其提供的命令如下:

### Create
```
$ eosc wallet create ${options}
```

Options:
-n, --name TEXT=default 钱包的名称,默认名称为default

### Open
打开已创建的钱包。钱包只有处于打开状态,才能对其进行进一步的操作。
```
$ eosc wallet open ${options}
```
Options:
-n,--name TEXT 所要打开钱包的名称

### Lock
对钱包进行加锁,一旦加锁后,就不能再对钱包进行其他操作了,解锁后才可进一步操作。

```
$ eosc wallet lock ${options}
```

Options:
-n,--name TEXT 需要加锁的钱包名称

### Unlock
对钱包进行解锁。

```
$ eosc wallet unlock ${options}
```
Options:
-n,--name TEXT 需要解锁的钱包名称
--password TEXT 钱包密码,这个密码是在创建钱包时生成的

### Import private key into wallet
把私钥导入到钱包中,如果你想使用某一账号进行转账等操作,则此账号对应的私钥必须导入到钱包中才能进行。

```
$ eosc wallet import ${options} key
```
Positionals:
key TEXT 将要导入的私钥,格式为 WIF。

Options:
-n,--name TEXT 钱包名称

### List
罗列出所有打开的钱包, *号标示的钱包表示其状态为 unlocked

```
$ eosc wallet list
```

### Keys
罗列出所有unlocked状态钱包中的私钥,格式为 WIF。

```
$ eosc wallet keys
```
# 钱包**

在上一章中我们介绍了钱包中其实保存的就是**信息,在本章中我们具体介绍这些**是如何生成的。

### 私钥
#### 私钥的重要性
私钥非常重要,可以说你账户的安全性就是通过私钥保证的。如果其他人知道了你的私钥信息,则他可以对你的EOS 账号进行任何操作。在大部分区块链系统中,如果丢失了私钥,就意味着丢失了私钥所对应的账户余额信息,你是无法通过其他方式找回的,因此网上提供了很多热备份,冷备份,硬件备份等私钥备份方案。在EOS系统中,虽然存在着账号恢复的手段,但私钥泄密后,账户上的余额也随时可能会被转走,因此,妥善保管私钥是保存区块链数字资产的关键。

#### 私钥的生成
那私钥到底是什么东西?其实它就是一个数字,是一个由256位的二进制组成的数字。这个数字是随机产生出来的,随机产生的目的是为了避免出现重复。既然是256个二进制数据,那产生方式就有很多了,如果你足够有耐心,甚至可以通过抛掷256次硬币的方式来产生,将硬币的正反面转换为0和1,由此得到一个256位的二进制数字。其本质是在1~2^256之间选择一个数字。计算机的实现一般是通过一个密码学安全的随机源中取出一长串随机字节,对其使用SHA256哈希算法进行运算,这样就可以方便的产生一个256位的数字。
私钥在EOS中的保存是使用WIF(Wallet Import Format)格式的,这种格式广泛的应用在钱包之间**的输入和输出。WIF还有一个压缩版本的格式,所谓的压缩主要是用来区分其公钥是否进行压缩,在区块链交易过程中,公钥大量被使用,因此对其压缩可以缩减交易的字节数。
#### 私钥不同格式的转换
通过以上介绍,你已经了解了三种私钥的形式,他们分别是256位二进制格式,WIF未压缩格式和WIF压缩格式,他们之间如何相互转换?

假设随机生成的私钥如下:

```
P = 0x9B257AD1E78C14794FBE9DC60B724B375FDE5D0FB2415538820D0D929C4AD436
```

添加前缀0x80

```
WIF = Base58(0x80 + P + CHECK(0x80 + P) + 0x01)
= Base58(0x80 +
0x9B257AD1E78C14794FBE9DC60B724B375FDE5D0FB2415538820D0D929C4AD436 +
0x36dfd253 +
0x01)
```
其中CHECK表示两次sha256哈希后取前四个比特。前缀0x80表示私钥类型,后缀0x01表示公钥采用压缩格式,如果用非压缩公钥则不加这个后缀。WIF格式的私钥的首字符是以“5”,“K”或“L”开头的,其中以“5” 开头的是WIF未压缩格式,其他两个是WIF压缩格式。

#### 加密私钥
正应为私钥在区块链中格外的重要,因此促进了加密私钥标准BIP0038 的出台,该标准能够被众多不同的钱包和比特币客户端理解,实现私钥的加密。

BIP0038 加密方案是:输入一个私钥,使用WIF对私钥进行编码,此外,让用户再输入一个长密码作为口令,通常是由多个单词或者一段复杂的数字字母字符串组成。通过加密之后,最终得到的结果是一个加密私钥,前缀为6P。

因此,当你看到了一个以6P开头的**,说明该**被加密过,需要一个口令来将其转换为WIF格式的私钥。

### 公钥
公钥的设计就是为了在网络中传输的,它可以保证使用者即便没有私钥,仍然可以通过公钥证明交易就是公钥所对应的账号产生的。其重要的三个特性如下:

1. 公钥是由私钥计算出来的,使用公钥加密的数据,私钥可以解码
2. 公钥无法逆向计算出私钥
3. 用私钥计算的签名,可以通过公钥进行验证

#### 公钥的生成
在椭圆加密算法(ECC)流行之前,绝大多数的公钥加密算法都是使用RSA,DSA这些基于模运算的替代加密系统,这些加密算法在今天依然占据非常重要的位置。但相比于这些算法,椭圆加密算法有其特殊的优势:

1. 安全性能更高, 如160位ECC与1024位RSA,DSA有相同的安全强度
2. 计算量小,处理速度快,在私钥的处理速度上(解密和签名),ECC远比RSA,DSA快得多
3. 存储空间占用小,ECC的**尺寸和系统参数与RSA,DSA相比要小得多
4. 带宽要求低使得ECC具有广泛的应用前景

因此,区块链的公钥生成算法一般都使用了椭圆加密算法,EOS也不例外。

椭圆曲线的定义非常简单,满足下面公式的所有(x,y)坐标的集合,就是我们所说的椭圆曲线:

`y² mod p = (x³ + 7) mod p`

上面的公式中,mod 是取余符号,而 P 是一个很大的素数。因此公钥的几何意义,其实就是椭圆曲线上的一个点,由一对坐标(x,y)组成。公钥通常表示为前缀04紧接着两个256比特的数字。04是类型标记,表示无压缩公钥。之后的两个256位分别对应着x和y坐标,共计65字节。

而公式中的P 取不同素数的时候,椭圆曲线会呈现出完全不同的形态,P越大,这个椭圆也就越大,可承载的数值范围也就越大,冲突率会降低,乃至于更安全,所以出于安全性考虑,比特币中采用的是一个特定的椭圆曲线,我们叫它spec256k1,它是由NIST(National Institute of Standards and Technology)这个组织确定的。spec256k1所选取的P有多大呢? 我们可以看一下:

```
p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
```

根据P 的选取,椭圆曲线相当于被定义在一个素数阶的有限域内,而不是定义在实数范围,他的函数图像看起来像分散在两个维度上的散点图。针对曲线上的点,我们可以定义加法和乘法运算,而公钥的产生正是使用了乘法运算,如下:

```
{K = priv * G}
```
其中priv是随机生成的私钥,G是椭圆曲线上的某一个点,而K 则是生成的公钥。G这个点称作生成点,它是spec256k1标准的一部分,可以认为是规定的一个固定的值。因此,根据私钥priv就可以生成公钥K,priv 和K 之间的关系是固定的,但只能单向运算,即从priv得到K。


#### 公钥的格式
公钥常见的有两种格式,一种是未压缩格式公钥,另一种是压缩格式公钥。引入压缩格式公钥是为了减少区块链交易的字节数。其中,未压缩格式公钥使用04作为前缀,之后是两个256比特,分别对应椭圆曲线点的x和y坐标,示例如下:

```
x = 97FCFAA24237514FD4C00A33491F835D7D019DE4E9CEB0E24916371BAE329E62
```

```
y = 2260575B83A1542D93418DABBBE65109B4E27A1A0737B2FD980698C3D0188839
```

则未压缩的公钥表示为:

```
K = 0x0497FCFAA24237514FD4C00A33491F835D7D019DE4E9CEB0E24916371BAE329E622260575B83A1542D93418DABBBE65109B4E27A1A0737B2FD980698C3D0188839
```

以上公钥共需65个字节来表示。

由于公钥就表示椭圆曲线上的一个点,我们从椭圆曲线的公式可以看到,在已知x 的情况下,我们可以求算出y 的两个解,在实数域它们显然是一正一负两个值;而在spec256k1椭圆曲线上则是一奇一偶两个数。那么只需记录x坐标和y的奇偶性(而不是y本身),这样我们就能砍掉近一半的空间表示同样的公钥,如下:

```
K' = 0x0397FCFAA24237514FD4C00A33491F835D7D019DE4E9CEB0E24916371BAE329E62
```
这个K'被称为压缩公钥,首字节是0x02(对应偶数y)或0x03(对应奇数y),公计33字节。

### EOS 公钥



EOS源码分析(4)钱包

EOS源码分析(4)钱包EOS源码分析(4)钱包

网址:http://www.qukuailianxueyuan.io/

EOS源码分析(4)钱包

EOS源码分析(4)钱包

欲领取造币技术与全套虚拟机资料

区块链技术交流QQ群:756146052  备注:****

尹成学院微信:备注:****

EOS源码分析(4)钱包

EOS源码分析(4)钱包

EOS源码分析(4)钱包EOS源码分析(4)钱包

网址:http://www.qukuailianxueyuan.io/

EOS源码分析(4)钱包

EOS源码分析(4)钱包

欲领取造币技术与全套虚拟机资料

区块链技术交流QQ群:756146052  备注:****

尹成学院微信:备注:****

EOS源码分析(4)钱包