先理解以太坊的私钥、公钥、地址指的什么意思。
私钥:一组64位的16进制字符,256位的随机数(32字节),用于发送以太的交易中创建签名来证明自己对资金的所有权。
公钥:私钥通过椭圆曲线加密secp256k1算法单向生成的512位 (64字节)数。
以太坊地址:由未压缩公钥的 Keccak-256 单向哈希(现在成为sha3_256),取最后20个字节(40位)派生出来的标识符。
生成流程:
①私钥 (private key)
伪随机数(或者secp256k1椭圆曲线算法)产生的256bit私钥示例(256bit 16进制32字节)
ee1ff0b356b996fb1db279533d54bb3f2d31b43cbbc07e8f727d8780eed1d09e
②公钥 (public key)
1. 采用椭圆曲线数字签名算法ECDSA-secp256k1将私钥(32字节)映射成公钥(65字节)(前缀04+Y公钥+X公钥):
04
Y(b4a3a960c949d42dfc013b9f3c59569ada518f0aeee45c110470a63b17471950)
X(9ffb11904aa5fdb20d58b3e86474fffcc58b560a18ae4c3170f05b5162c15f37)
2. 拿公钥(非压缩公钥)来hash,计算公钥的 Sha3_256 哈希值(32bytes):
263DE9A0EC149B5B91EAB81121E174234E45103EE1FDD1A6D89385FAA4283E0C
注意:经过测试,非压缩公钥需要除去前缀04,并且转换为字节字符串,进行sha3_256哈希,才能得到正确的hash值匹配地址
3. 取上一步结果取后20bytes即以太坊地址:
21E174234E45103EE1FDD1A6D89385FAA4283E0C
③地址 (address)
0x21E174234E45103EE1FDD1A6D89385FAA4283E0C
最主要的还是libsecp256k1椭圆曲线算法原理,在这里就不做多的讲解:
请参考比特币官网对secp256k1的介绍:https://en.bitcoin.it/wiki/Secp256k1
原理看完后也许还是不清楚如何转换成代码来进行操作,刚好网上是有libsecp256k1库的需要自己进行编译。无论是比特币还是以太坊或者web3j底层内部其实都是调用libsecp256k1库来进行封装使用的。因此只需要会使用libsecp256k1库的接口,问题不大。
libsecp256k1库:https://github.com/bitcoin-core/secp256k1
代码流程:
string EthSignature::getETHAddress(string privatekey)
{
char prikeyhex[65];
strcpy(prikeyhex,(char*)(privatekey.data()));
int len = sizeof(prikeyhex) / 2; // 私钥长度 - 32字节
unsigned char prikey[len]; // 私钥存储
int ii; // 索引值
int ret; // 返回值
unsigned char CPubKey[65]; // 公钥存储
size_t clen; // 返回公钥长度
secp256k1_context *secp256k1_context_sign;
secp256k1_pubkey pubkey; // secp256k1返回公钥
// 将私钥字符串转换为字节存储
for(ii = 0; ii < sizeof(prikeyhex); ii+=2){
prikey[ii/2] = hex2int(prikeyhex[ii]) * 16 + hex2int(prikeyhex[ii + 1]);
}
// 打印私钥
printf("Private key: ");
for(ii = 0; ii < len; ii++)
{
printf("%02x",prikey[ii]);
}
printf("\n");
// 生成公钥
secp256k1_context_sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, prikey);
char data[131];
int offset = 0;
// 打印公钥
if(ret){
printf("Public key : ");
printf("[X(");
for(ii = 63; ii >= 32; ii--){
printf("%02x", pubkey.data[ii]);
}
printf("):Y(");
for(ii = 31; ii >= 0; ii--){
printf("%02x", pubkey.data[ii]);
}
printf(")]\n");
// 获取压缩公钥
clen = 65;
secp256k1_ec_pubkey_serialize(secp256k1_context_sign, CPubKey, &clen, &pubkey, SECP256K1_EC_COMPRESSED);
printf("Compressed key : ");
for(ii = 0; ii < clen; ii++){
printf("%02x", CPubKey[ii]);
}
printf("\n");
// 获取非压缩公钥
clen = 65;
secp256k1_ec_pubkey_serialize(secp256k1_context_sign, CPubKey, &clen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
printf("Uncompressed key: ");
for(ii = 0; ii < clen; ii++){
offset += sprintf(data+offset,"%02x", CPubKey[ii]);
}
data[offset] = '\0';
printf("\n");
}
if (secp256k1_context_sign) {
secp256k1_context_destroy(secp256k1_context_sign);
}
//(前缀04+X公钥+Y公钥)
//公钥(非压缩公钥)来hash,转换为字符串,计算公钥的 Keccak-256 哈希值(32bytes)
string da(data);
string cc = m_pOperation->hexStringToString(da.substr(2),128,"");
string str=sha3_256(cc);
string address = "0x"+str.substr(str.size()-40);
return address;
}
参考:
https://www.cnblogs.com/kumata/p/10591394.html
https://www.cnblogs.com/wanghui-garcia/p/9646508.html
今天的文章以太坊钱包私钥怎么查看_虚拟币钱包密钥分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/88278.html