1. 什么是账户?
乙太坊是一个P2P网络,任何人只要有一台可以联网的电脑,都可以参与到这个网络中。
普通用户参与到乙太坊网络中,有两种目的:
最常见的目的,就是进行乙太币交易。
比方说A要把100个ETH转给B,这就会生成一比交易。这笔交易会被打包到一个区块中,由矿工将其加入区块链中。矿工做这件事的过程就是记账,或者称之为挖矿。当然,矿工不是义务劳动,是需要收取手续费的,并且还会得到奖励。
当然,还有另外一种目的,那就是部署和调用智能合约。
这是一种更高级的玩法,可以在A和B之间形成一个在某种条件下可以强制执行的合约。举个简单的例子,A和B之间部署了这么一种合约,合约规定:1)2018年1月1号,A和B分别往合约账号中充值价值100美元的ETH。简单起见,比方说一个ETH价值1美元,那么每个人,都会冲100ETH到合约账户中;2)2018年2月1号时,合约账户向A转移价值100美元的ETH,剩下的ETH全部转给B。
这个合约乍一看有点绕,但是仔细想想,逻辑很清晰:如果相对于1月1号,2月1号时ETH升值了,比方说涨到了2美元,那么A只能从合约账户中得到50个ETH,而剩下的150ETH会全部转给B。说得更白话一些,这其实是一个对冲合约:A是看跌的,B是看涨的。因为涨的时候,B可以得到更多的ETH,而跌的时候,A可以得到更多的ETH。
如果2月1号时,ETH涨到了2美元,A想反悔怎么办?对不起,合约代码已经写到了区块链中并且无法更改,2月1号会强制执行,A只能怪自己没有判断对形势,B只顾数钱就行了,不用担心A会耍赖。
说了这么多,我们要回到本文的主题。在以上两种目的中,参与者A和B,其实就是乙太坊中的最常见的账户,我们称为外部账户(EOA: Externally Owned Account)。我们提到的合约,也被维护在一个账户中,即合约账户(CA: Contract Account)。
在乙太坊网络中,账户的状态信息是全局的,这些状态会被一种特殊的数据结构(MPT:默克尔前缀树)保存到世界状态中,比方说账户A的地址,余额,交易的次数等等,比方说合约账户的地址,余额,合约代码等等。
今天我们详细说一下外部账户EOA,合约账户放到下一章来说。
2. 公钥和私钥
每个账户都会由一对私钥和公钥组成。
每个账户都有一个地址,而这个地址,就是交易时用的地址。A往B转100ETH,其实就是B的地址转100ETH。这个地址,就像我们的银行卡号一样,可以公开的随便告诉别人(不告诉别人,别人怎么把钱转给你?)。
私钥,公钥和地址的关系是这样的:
私钥经过一种哈希算法(椭圆曲线加密算法ECDSA-secp256k1)计算生成公钥,然后取公钥的最后160位二进制(通常表现为40位的16进制字符串)形成了地址。
其中,公钥和地址都是可以公布的,而私钥,你只能自己悄悄的藏起来,不要丢失,因为你的账户中的资产也会跟着丢掉;不要被别人盗取,因为账户中的资产也会随着被盗取。所以,私钥的保存非常重要。
在比特币世界中,私钥的保存方式是:把一串很长的私钥用你能想到最可靠的办法保存起来,比方说写到一张纸条上然后把它藏到喜马拉雅之颠;私钥的保存,甚至催生一条产业链和一批创业公司,比方说电子硬件钱包,专门帮你保存私钥到一个便携的设备中。
在乙太坊的世界中,私钥的表现形式和保存方式又不一样了:它由一个密码和一个keyfile组成。这个密码就是我们通常在互联网上注册账户时用的密码,就像你的淘宝账户密码。当然你最好把这个密码设置得尽量复杂一些,尽量别用生日,手机号,或者1111111,以防轻易被他人破解。而keyfile则是一个明文的JSON格式文件,里面保存的是私钥的加密信息。乙太坊的客户端,可以通过密码和keyfile,解密出私钥。
意思是说:耶!我们不用记那一串的私钥了!
但是,我们要记住密码,并且把keyfile保存好了!如果丢了密码和keyfile的任何一个,对不起,你的钱也丢了。
3. 账户的创建
创建一个账户,其实就是要创建一个密码加一个keyfile。当然,通过密码和keyfile,程序也会自动生成公钥和账户地址。
这里要说一件有意思的事情,当你在乙太坊创建一个账户时,有一些与传统的中心化的系统截然不同的现象:
(1)你的账户(包括私钥,密码,keyfile,公钥和地址)不会被记录到乙太坊系统的数据库中(也就是区块链中)
(2)你不需要告诉任何人你创建了一个账户,他们也不需要知道,除非有人要给你转账。
(3)你也不需要运行乙太坊的客户端
(4)你甚至不用联网,离线的创建
你所要做的,就是保存好你的密码和keyfile,然后当别要给你转账时,把你的账户地址(40位的字符串)告诉别人就行了。剩下的,就交给乙太坊。
当有人往你的地址转了一笔ETH后,你只需打开乙太坊的钱包,用你的密码和keyfile恢复账号(恢复步骤),然后就能看到这笔钱了。
下面,我们看一下如何创建账号,简单得不能再简单了,运行如下命令:
1 | geth account new |
这个命令会提示你输入密码。完成后,会提示你keyfile的存储路径,并提示你保存。
使用如下命令可以查看创建好的账户:
1 | $ geth account list |
注:geth是乙太坊的go语言版客户端,你需要提前下载和安装它。