Skip to content

Instantly share code, notes, and snippets.

@felix021
Last active November 3, 2022 10:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save felix021/93bf38167f2380a556292a6caed09d99 to your computer and use it in GitHub Desktop.
Save felix021/93bf38167f2380a556292a6caed09d99 to your computer and use it in GitHub Desktop.
以太坊的私钥、公钥、地址
/*
* 安装nvm和相应npm包
* $ nvm install v8.9.4
* $ npm install keccakjs secp256k1
*/
const { randomBytes } = require('crypto')
const secp256k1 = require('secp256k1')
const SHA3 = require('keccakjs')
/*
* 私钥:secp256k1(ECDSA)的私钥(256 bits 随机数)
*/
//生成随机私钥
function generatePrivateKey()
{
let private_key
do {
private_key = randomBytes(32)
} while (!secp256k1.privateKeyVerify(private_key));
return private_key
}
//导入16进制编码的私钥
//e.g. openssl rand -hex 32
function loadPrivateKeyFromHexString(hex_string)
{
if (hex_string.slice(0, 2) == '0x') {
hex_string = hex_string.slice(2);
}
if (hex_string.length != 64) {
return null;
}
return new Buffer(hex_string, 'hex')
}
/*
* 公钥:在secp256k1规范下,由私钥和规范中指定的生成点计算出的坐标(x, y)
* 非压缩格式公钥: [前缀0x04] + x + y (65字节)
* 压缩格式公钥:[前缀0x02或0x03] + x ,其中前缀取决于 y 的符号
*/
//生成公钥: 输入的私钥应当是buffer
function generatePublicKey(private_key, compressed = false)
{
let public_key = secp256k1.publicKeyCreate(private_key, compressed)
return public_key //包含了前缀
}
/*
* 地址:公钥的sha3-256编码的后20字节,16进制编码的字符串
*/
function generateAddress(public_key)
{
let h = new SHA3(256)
h.update(public_key.slice(1)) //去掉前缀
return h.digest('hex').slice(-40)
}
//let private_key = generatePrivateKey()
let private_key_hex = '22a0b3688dd46ab1a37d6237871913037681d57f628862336bc9c3c468c4a449'
let private_key = loadPrivateKeyFromHexString(private_key_hex)
console.log(private_key.hexSlice())
let public_key = generatePublicKey(private_key)
console.log(public_key.hexSlice())
let address = generateAddress(public_key)
console.log(address)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment