九州体育网 - 十年信誉网站

关于作者

EOS映射完全指南

九州体育网 / 九州编程 / ... / Reads: 1

随着EOS主网即将上线,EOS映射这个事情就必须在主网上线前完成。

什么是EOS映射?

简单地说,目前的EOS实际上是基于ETH主网发行的Token,等到EOS主网上线时,必须有一种机制能够把基于ETH地址的EOS Token给“转移”到EOS主网地址上,这个过程就是映射。

不做映射行不行?

不做映射将导致持有的EOS Token在主网上线后被清零,也就是无偿销毁,给其他EOS持有人做了一点微小的贡献。

那么EOS映射的原理是什么呢?

假设小明持有某个ETH地址的EOS Token,通过映射,到了6月份,小明持有的ETH地址的EOS Token作废,取而代之的是他将在他持有的EOS地址上获得等量的EOS。

EOS Token自身存储在ETH的合约中,因此,任何人都可以获得ETH地址->EOS数量的映射表,但是要把ETH地址的EOS转移到将来真正的EOS地址,就还需要一个ETH地址->EOS地址的映射表,这个映射表实际上也在ETH的合约中,但是,注册ETH地址->EOS地址的过程是手动的,原因是,只有持有ETH地址私钥的人能力注册对应的ETH地址,这样保障了EOS Token持有人能力设置自己的EOS地址。

因此,映射原理简单地来说就是:

小明持有某个ETH地址的私钥(记作eth_priv)以及对应ETH地址(记作eth_addr)的EOS Token;

小明必须手动创建一个EOS地址的私钥(记作eos_priv)以及对应的EOS地址(记作eos_addr);

最后,小明通过调用合约的注册方法,传入自己的eth_addreos_addr,完成映射。由于这个过程需要私钥eth_priv签名,所以其他人不可能把小明的ETH地址映射到自己的EOS地址上。

映射过程中,要保障保险,就要确保创建EOS私钥eos_priv的过程绝对保险。

EOS官网提供了一个在线创建EOS私钥和对应地址的页面:

https://eos.io/distribution

点击REGISTER EOS KEY可以获取一个在线生成的EOS私钥及地址:

eos-key-register

以上图为例,我们获取到的EOS私钥是5Jd6Zhcv1DWCZkRHb6pGNjpRAYZ5m2HBDC3u555jCuCD3nmnUgZ

做完映射后,最关键的问题是必须保存私钥,并且直到官方钱包可用后,能力把私钥导入到钱包中。在此期间,如果私钥被泄漏,主网上线后的EOS就不属于你了。

能不能用现有的ETH私钥作为EOS私钥?这样,映射完成后,就不必保存私钥,上线后直接导入ETH私钥,这样更方便。

这种方式是可行的。我们来看一下EOS私钥和地址的编码格式。

通过对EOSIO的eosjs-ecc的JavaScript源码分析可知,EOS私钥编码格式和Bitcoin的非压缩格式私钥编码完全一致,而EOS地址的编码就比较奇葩,它的算法是:

  1. 计算压缩格式的33位公钥;
  2. 取RipeMD160结果的前4位作为checksum;
  3. 把33位公钥和4位checksum连起来,用Base58编码,但不使用Base58的checksum;
  4. 加上前缀EOS即为最终地址。

地址不是公钥哈希,而是包含公钥,是不是无比山寨?

先不吐槽了,言归正传,现在我们需要共享ETH私钥和EOS私钥,假设我们拥有ETH私钥:

0x6a49b749ee5588e7d8f59e42848072ba0de3484370f23afe12aea1ca16f89761

通过下面的代码就可以正确转换成EOS私钥和EOS地址:

// THE CODE IS PROVIDED ON AN "AS IS" BASIS, AND NO WARRANTY,
// EITHER EXPRESS OR IMPLIED, IS GIVEN.
// YOUR USE OF THE CODE IS AT YOUR SOLE RISK.
const
    ethUtil = require('ethereumjs-util'),
    bitcoin = require('bitcoinjs-lib'),
    wif = require('wif'),
    bs58 = require('bs58');

let
    ethPriv = '0x6a49b749ee5588e7d8f59e42848072ba0de3484370f23afe12aea1ca16f89761',
    rawPriv = Buffer.from(ethPriv.substring(2), 'hex'),
    ethAddr = '0x' + ethUtil.privateToAddress(rawPriv).toString('hex'),
    btcPriv = wif.encode(0x80, rawPriv, true),
    eosPriv = wif.encode(0x80, rawPriv, false);

let
    compressedPub = bitcoin.ECPair.fromWIF(btcPriv).getPublicKeyBuffer(),
    checksum = bitcoin.crypto.ripemd160(compressedPub),
    addr = Buffer.alloc(compressedPub.length + 4);
compressedPub.copy(addr, 0);
checksum.copy(addr, compressedPub.length, 0, 4);

let eosAddr = 'EOS' + bs58.encode(addr);

console.log('Raw Private: ' + rawPriv.toString('hex'));

console.log('ETH Address: ' + ethAddr);
console.log('BTC Private: ' + btcPriv);
console.log('EOS Private: ' + eosPriv);
console.log('EOS Address: ' + eosAddr);

执行结果如下:

Raw Private: 6a49b749ee5588e7d8f59e42848072ba0de3484370f23afe12aea1ca16f89761
ETH Address: 0xb289c33560b6ef88ce481406f61b04a93f6ffaa0
BTC Private: KznKZLHWwxBt3YeCDWfcrwzHf8Gc1JeQ4omnpy1sHXNUAsBzpT7q
EOS Private: 5Jd6Zhcv1DWCZkRHb6pGNjpRAYZ5m2HBDC3u555jCuCD3nmnUgZ
EOS Address: EOS7nmwuAaB8WvYXJuH3YkXHGh7ABk4njitZRkjKCgaFCLcXEpAfA

生成的EOS私钥及EOS地址和官网生成的完全一致,说明转换正确。

对于普通用户来说,把生成的EOS地址作映射,就不必保存EOS私钥。

对于交易所这种拥有大量ETH地址的机构来说,通过计算ETH私钥对应的EOS地址来映射,可以防止额外生成并持有大量EOS私钥。

最后友情提醒:

除了EOS官网,不要使用任何第三方网站在线生成的EOS私钥!

映射过程只需填写EOS地址,不能填写EOS私钥!

本文中的代码可自由使用,但未经全面测试,不担当任何责任。使用本文中的代码造成的任何后果完全自负!

Comments

Make a comment

WARNING: You are using an old browser that does not support HTML5. Please choose a modern browser (Chrome / Microsoft Edge / Firefox / Sarafi) to get a good experience.