如何闭上眼睛默念咒语,就能生成自己的钱包
昨天发出《送你几个存有以太币的钱包、以及它们的密码》的文章以后,有工程师的朋友想知道关于密钥如何得出钱包地址的过程。我用代码回答一下这个问题。
密钥
首先,你要先选一个密钥。这个密钥是从 0 到 2 的 256 次方之间的任意一个数字。
6 也行,18 也行,3333333333,123123123123123123123123123123 都行。
你可以在不联网的情况下,闭上眼睛,心里默念一个数字,你的钱包就生成了。就是这么心想事成。这个数字就开启区块链世界大门的「咒语」。
你想的数字是什么呢?是 123456 吗?
如果以太坊真的让大家自己选密码的话,那就乱了套了。人类估计有 10% 会选 123456 这样的密码。所以只要是个正经钱包应用,都不会给人类自己选密码的选择,它们会帮你随机生成一个,然后千方百计说服你把密码记下来。比如,机器随机帮你选的数字是这个样子的:
90911452373928472265288749637003951760509809577710983576295184074863909042086
或者是这个样子的:
28555159302308507010158743376625458935295478710676475386408420385292396357292
你就知道,计算机给的密钥,和自己选的密码的复杂程度,不是一个数量级的。
这个密码看起来是一个字符串(因为太长。。。了),但实际上他依然是一个很大很大的数。这里我故意用了 10 进制,而不是 16 进制,使得它看起来更像一个普通的数字,而不是一个字符串。
到哪里登记密码呢?
我相信很多人拿到这个密码以后,你是不是有一种冲动,想去什么地方注册一下,好让这个密码生效?这个地方可能是某个网站,或者某个银行,或者某个政府机构?「如果我不登记一下我的密码,下一次我输入密码的时候,别人怎么知道我的密码是输对了还是输错了呢?」
我们有这种冲动,是因为我们就像《肖申克的救赎》里面的安迪一样,身体已经离开了度过一生的监狱,心理还没有独立,一定要举手,有人批准以后才会上厕所。我们被现实世界,包括互联网世界囚禁得太久了,不登记一下不放心。
在加密世界,我们终于从任何其他的机构和个人那里独立出来了,没有那个批准的人了。只要自己在纸上写上一个足够长的随机数,并且记住它,我们就拥有了数字世界的钥匙。
这难道不神奇吗?如果这是真的,难道不会让我们重新审视和思考一下未来吗?
让我们继续我们的新世界之旅。
钱包地址
私钥有了,别人怎么给我转钱?我把这个私钥告诉别人吗?当然不是,我们要生成一个公开的地址。
我们用私钥(也就是任何一个 0 到 2 的 256 次方之间的数字),可以直接生成钱包地址。
大家看下面的 JavaScript 代码的第 10 行:
web3.eth.accounts.privateKeyToAccount(privateKey)
这个函数就帮你从心中的那个秘密算出对应的钱包地址。(例子中,我依然用数字 6 作为密钥,得到了昨天我们四十大盗藏好的 0.0001 个以太币的地址。实际使用的时候,千万不要用这个例子的钱包。)
你现在可以把算出来的那个地址满世界的分发了。
如果有善良的朋友愿意给你打几个以太币,它就可以直接打到上面这个地址了。直到这里,你不需要使用你的私钥,这个私钥就如同「芝麻开门」这个咒语一般,记在心里就好。
下面这段程序,就是算出密码从 1 到 1000 的前 1000 个账户的钱包地址
使用账户
接下来的问题是,我心中的咒语怎么使用呢?我怎么向别人证明我知道这个咒语呢?
验证密码最常用的方法,就是我把密码告诉你(或者服务器,或者银行),你把这个密码和我以前登记的密码对比一下,相同就通过,就帮我办事(执行操作、或者转钱啥的),不一样就拒绝。
但这个前提是我们要信任对方。比如银行。因为银行完全有能力不经过我输入密码就把我的钱都转走的,只不过我如此(盲目)的信任它,否则我就别存钱了。
但是在加密世界,第一,不存在这样的我们信任的中间方。第二,一旦我把密码给过任何其他人,他只要记住我的密码,我的所有的钱,所有的资产,就全是他的了。
有什么办法,在我不告诉任何人(任何人!)密码的前提下,验证我知道密码吗?
有的。叫签名。
签名
比如有人给你发了一段信息,比如 「锄禾日当午」,你可以把这一句话,和你的私钥一起计算,得到一串数字。这个过程叫做签名(参看下面代码第 19行):
const signed = account.sign('锄禾日当午')
返回数字如下:
0x9ba5b4103ba0edf19de989b5abc 93003da8eb38172dae4346bf035b8 730e6f5b0aea52cd1643487c6aafcc 3d530637735b1aef67f4a9884d70ae 20b09f18c80b1c
很显然,如果不知道自己那个天文数字一般的密钥,靠蛮力是猜不出上面这个更加复杂的结果。
你可以把上面的这串数字还给对方了。
至于怎么发?用程序也行,电子邮件也行,顺丰快递也行,或者耐着性子打电话念给他也行,总之,自己的私钥打死我也不告诉任何人,但用密钥计算出来的数字,可以随便告诉。
对方拿到以后,把原始的字符串「锄禾日当午」以及你给他的这一串数字一起给 recover 函数,这个函数会返回一个地址:
0xE57bFE9F44b819898F47BF37E5AF72a0783e1141
这个地址,就是你的钱包地址。
也就是说,对方虽然不知道你的密钥,但是可以 100% 的确信,发给他那一串数字的人,是如上这个地址的拥有者,因为从数学上可以验证,不知道密钥还能蒙对那段数字,不可能。
连真人都去可以这样验证,对于区块链上的程序更是这样。如果有人发起一笔交易的申请(可以是别人也可以是你),你只要对于这个交易的数据用自己的私钥签名一下,区块链上上的所有人(包括所有的记账的人),就都相信这个交易真的是这个账户的拥有者授权的,就会把你的账户的钱按照交易里面的付款接收方和金额进行变动。反过来,只要没有那一个密钥签名,任何人,包括你自己,也无法做任何交易。
密钥从来不在网络上传输,传输的只有签名
大家可能注意到了,这个过程中,密钥从来不在网络上传输。只是需要签名的时候,你用这个数字和输入的信息做一个签名运算就可以。
所谓的冷钱包,就是这样的设备:它存储密钥(那个大大的数字),但是不联网,保存在安全的地方,就如同躲在地堡里的总统一样。如果需要转账,你可以拿着需要签名的信息到他那里,让他离线的算出一个数字,然后拿着这个数字回到联网的电脑旁边,就可以无比安全的完成交易。
总结
今天希望给大家带来一个小小的「啊哈」时刻,帮助大家真切地理解,为什么那么多人都玄而又玄的说,「区块链世界是去中心的」,为什么他们都说「直到今天,人类的资产才第一次独立了」。
其实这些不准备让人理解的大词儿,指的就是刚才说的,「自己的密钥自己生成,自己保存,谁都不给,密钥不泄露,资产就在那里」的这回事儿。
不要问比特币为什么波动,而是要站在比特币的角度问,为什么美元在波动?