以太坊中的账户

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
2
3
4
5
$ geth account list

account #0: {a94f5374fce5edbc8e2a8697c15331677e6ebf0b}
account #1: {c385233b188811c9f355d4caec14df86d6248235}
account #2: {7f444580bfef4b9bc7e14eb7fb2a029336b07c9d}

注:geth是乙太坊的go语言版客户端,你需要提前下载和安装它。