ruby 以太坊将私钥转换为地址(公钥)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ruby 以太坊将私钥转换为地址(公钥)相关的知识,希望对你有一定的参考价值。
// Go Version
// openssl rand 32 -hex > ~/priv_key.txt
// go run main.go ~/priv_key.txt
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"encoding/hex"
"fmt"
"io"
"math/big"
"os"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/crypto/sha3"
)
func main() {
if len(os.Args) > 1 {
path := os.Args[1]
fileBuf, err := loadFile(path)
fmt.Println("Read private Key:", string(fileBuf))
if err != nil {
fmt.Println("load keyfile error!")
os.Exit(1)
}
hexBuf, _ := decodeHexString(fileBuf)
priv := ToECDSA(hexBuf)
pub := priv.PublicKey
ecdsaPubBytes := elliptic.Marshal(secp256k1.S256(), pub.X, pub.Y)
fmt.Println("public key string:", hex.EncodeToString(ecdsaPubBytes))
fmt.Println("public key bytes:", ecdsaPubBytes)
fmt.Println("public.X:", pub.X)
fmt.Println("public.Y:", pub.Y)
// byteLen := (secp256k1.S256().Params().BitSize + 7) >> 3
// fmt.Println(byteLen)
addressBytes := Keccak256(ecdsaPubBytes[1:])[12:]
fmt.Println("address bytes:", addressBytes)
fmt.Println("sha3 string:", hex.EncodeToString(Keccak256(ecdsaPubBytes[1:])))
fmt.Println("address string:", hex.EncodeToString(addressBytes))
} else {
fmt.Println("keyfile must be given as argument")
}
}
func decodeHexString(data []byte) ([]byte, error) {
return hex.DecodeString(string(data))
}
func loadFile(file string) ([]byte, error) {
buf := make([]byte, 64)
fd, err := os.Open(file)
if err != nil {
return nil, err
}
defer fd.Close()
if _, err := io.ReadFull(fd, buf); err != nil {
return nil, err
}
return buf, nil
}
func BytesToBig(data []byte) *big.Int {
n := new(big.Int)
n.SetBytes(data)
return n
}
func ToECDSA(prv []byte) *ecdsa.PrivateKey {
priv := new(ecdsa.PrivateKey)
priv.PublicKey.Curve = secp256k1.S256()
priv.D = BytesToBig(prv)
priv.PublicKey.X, priv.PublicKey.Y = secp256k1.S256().ScalarBaseMult(prv)
return priv
}
func Keccak256(data ...[]byte) []byte {
d := sha3.NewKeccak256()
for _, b := range data {
d.Write(b)
}
return d.Sum(nil)
}
// NodeJS version
// npm install keccakjs
// npm install secp256k1
const SHA3 = require('keccakjs')
let pubKeyHex = "046B8A6CC271D62F45301A3C6C443DC1879193CA1E4A8DF6CCFA8A82525F5A027C1333C132A93EA35857A30CB486BEF3045A4E33B29F18BC128A8EFF6C44074268"
let pubKeyBuf = new Buffer(pubKeyHex, 'hex')
let h = new SHA3(256)
h.update(pubKeyBuf.slice(1)) // 130 => 128
let address = h.digest('hex').slice(-40)
console.log(address)
# geth version
openssl rand 32 -hex > ~/priv_key.txt
geth account import ~/priv_key.txt
# Ruby version
# gem install digest-sha3
require 'openssl'
require 'digest/sha3'
curve = OpenSSL::PKey::EC.new('secp256k1')
curve.generate_key
prv = curve.private_key.to_s(16)
pub = curve.public_key.to_bn.to_s(16)
puts "Private Key: #{prv}"
puts "Public Key: #{pub}"
def decode(s, base)
syms = '0123456789abcdef'.freeze
s = s.downcase if base == 16
result = 0
while s.size > 0
result *= base
result += syms.index(s[0])
s = s[1..-1]
end
result
end
def encode(v, base)
syms = 256.times.map {|i| i.chr }.join.freeze
result = ''
while v > 0
result = syms[v % base] + result
v /= base
end
result
end
def public_to_address(str)
str = str[2, 128]
Digest::SHA3.hexdigest(encode(decode(str, 16), 256), 256)[-40..-1]
end
puts "Address: #{public_to_address(pub)}"
以上是关于ruby 以太坊将私钥转换为地址(公钥)的主要内容,如果未能解决你的问题,请参考以下文章