EOS的账户体系: wallet用来保管key,key是打开账户的钥匙
EOS是一个去中心化的操作系统。专为高性能去中心化应用而设计。EOS提供了数据库,许可,调度,验证以及应用间通信等功能。
怎么理解其账户体系 ?参考此文
eosc程序中创建key对的代码分析
// create key
create->add_subcommand("key", localized("Create a new keypair and print the public and private keys"))->set_callback([] {
auto privateKey = fc::ecc::private_key::generate();
std::cout << localized("Private key: ${key}", ("key", key_to_wif(privateKey.get_secret()))) << std::endl;
std::cout << localized("Public key: ${key}", ("key", string(public_key_type(privateKey.get_public_key())))) << std::endl;
});
注意这里用了两个key对,一个是冷备的owner所有者但是不管事;另一个是active,具体干活,但是不拥有
key具体分析
用了libraries目录下fc这个包的ecc(椭圆曲线)的方法
如下这个private_key类就是定义的类,还要看实现
如上只是定义,真正实现在elliptic_impl_priv.cpp中
public_key private_key::get_public_key()const
{
FC_ASSERT( my->_key != empty_priv );
public_key_data pub;
unsigned int pk_len;
FC_ASSERT( secp256k1_ec_pubkey_create( detail::_get_context(), (unsigned char*) pub.begin(), (int*) &pk_len, (unsigned char*) my->_key.data(), 1 ) );
FC_ASSERT( pk_len == pub.size() );
return public_key(pub);
}
里面调用了public_key.cpp的初始化函数:
//里面pubkey的前缀固定是EOS
#define KEY_PREFIX "EOS"
//生成public
public_key::public_key( const public_key_data& dat )
{
const char* front = &dat.data[0];
if( *front == 0 ){}
else
{
my->_key = EC_KEY_new_by_curve_name( NID_secp256k1 );
my->_key = o2i_ECPublicKey( &my->_key, (const unsigned char**)&front, sizeof(public_key_data) );
if( !my->_key )
{
FC_THROW_EXCEPTION( exception, "error decoding public key", ("s", ERR_error_string( ERR_get_error(), nullptr) ) );
}
}
}
如何在本地验证账户映射的Key是否正确
绝不能联网,我运行这个html是本地编辑好了,然后拔掉网线关掉wifi运行的(防止泄露,保证安全)
- 首先是安装验证工具,这样我home目录下eosio的目录下,除了eos目录外,多了一个eosjs-ecc目录,就是这个工具
git clone https://github.com/EOSIO/eosjs-ecc.git
cd eosjs-ecc
npm install
npm run build_browser
- 其次编写html,里面用script方式调用了eosjs-ecc并进行了验证,代码如下
<head>
<script src=eosjs-ecc.js>
</script>
</head>
<body>
<script>
var ecc = eosjs_ecc
var privateKey = '5KKyx6GkYg94phE9w863bpF8Wk8QRBLxGLWaerZgyErucd76G9Q' //'Here is your Private Key'
var pubKey = ecc.privateToPublic(privateKey)
document.write(pubKey)
document.write("<p>")
document.write(privateKey)
var expected_pub = 'EOS8PVv6vmhTe1azXHk1V7suzApuvesDCZJAwhYpj7RSfvN6JTpQ7' //'Your Public Key'
if (pubKey === expected_pub) {
document.write('<p> Valid Key!')
} else {
document.write('<p> The key is not valid, the input public key is:')
document.write(expected_pub)
document.write('<p> But the generated key is:')
document.write(pubKey)
}
</script>
</body>
</html>
- 拔掉网线 关掉wifi后运行
进一步深入了解js中是怎么生成私钥的
// 1.从cpu获取Entropy熵数据 2.keyUtils.random32ByteBuffer 3.没有联网的内容
PrivateKey.randomKey = function () {
var cpuEntropyBits = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
return PrivateKey.initialize().then(function () {
return PrivateKey.fromBuffer(keyUtils.random32ByteBuffer({ cpuEntropyBits: cpuEntropyBits }));
});
};
然后真正的key运算在keyUtils.random32ByteBuffer,都是一些位运算和hash运算
function random32ByteBuffer() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref$cpuEntropyBits = _ref.cpuEntropyBits,
cpuEntropyBits = _ref$cpuEntropyBits === undefined ? 0 : _ref$cpuEntropyBits,
_ref$safe = _ref.safe,
safe = _ref$safe === undefined ? true : _ref$safe;
assert(typeof cpuEntropyBits === 'undefined' ? 'undefined' : _typeof(cpuEntropyBits), 'number', 'cpuEntropyBits');
assert(typeof safe === 'undefined' ? 'undefined' : _typeof(safe), 'boolean', 'boolean');
if (safe) {
assert(_entropyCount >= 128, 'Call initialize() to add entropy');
}
// if(entropyCount > 0) {
// console.log(`Additional private key entropy: ${entropyCount} events`)
// }
var hash_array = [];
hash_array.push(randomBytes(32));
hash_array.push(Buffer.from(cpuEntropy(cpuEntropyBits)));
hash_array.push(externalEntropyArray);
hash_array.push(browserEntropy());
return hash.sha256(Buffer.concat(hash_array));
}