生成以太坊系地址

代码解析

要首先生成一个新的钱包地址,我们需要导入go-ethereum crypto包,该包提供用于生成随机私钥的GenerateKey方法。

privateKey, err := crypto.GenerateKey()
if err != nil {
  log.Fatal(err)
}

然后我们可以通过导入golangcrypto/ecdsa包并使用FromECDSA方法将其转换为字节。

privateKeyBytes := crypto.FromECDSA(privateKey)

我们现在可以使用 go-ethereum hexutil 包将它转换为十六进制字符串,该包提供了一个带有字节切片的Encode方法。 然后我们在十六进制编码之后删除“0x”。

fmt.Println(hexutil.Encode(privateKeyBytes)[2:]) // 4e6aaa173f18b6160aa6a36a4e54e4e79a5fff8a93d5efe5126c589f4464c052

这就是用于签署交易的私钥,将被视为密码,永远不应该被共享给别人,因为谁拥有它可以访问你的所有资产。

由于公钥是从私钥派生的,因此go-ethereum的加密私钥具有一个返回公钥的Public方法。

publicKey := privateKey.Public()

将其转换为十六进制的过程与我们使用转化私钥的过程类似。 我们剥离了0x和前2个字符04,它始终是EC前缀,不是必需的。

publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
	log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
}

publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA)
fmt.Println(hexutil.Encode(publicKeyBytes)[4:]) // 405701f955192319aa5c0b9d7564cd0ff184a498dc12c5bda941c91354382dbf44ff6f1678ba3ea0bf9a545895c00ab7cfb2fbcf0c5cca97569a4bf0aed996c8

现在我们拥有公钥,就可以轻松生成你经常看到的公共地址。 为了做到这一点,go-ethereum加密包有一个PubkeyToAddress方法,它接受一个ECDSA公钥,并返回公共地址。

address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()
fmt.Println(address) // 0xe83FF792C385d6935d3b1f58c40de2BDEe3621e9

公共地址其实就是公钥的Keccak-256哈希,然后我们取最后40个字符(20个字节)并用“0x”作为前缀。 以下是使用 golang.org/x/crypto/sha3 的 Keccak256函数手动完成的方法。

hash := sha3.NewLegacyKeccak256()
hash.Write(publicKeyBytes[1:])
fmt.Println(hexutil.Encode(hash.Sum(nil)[12:])) // 0xe83ff792c385d6935d3b1f58c40de2bdee3621e9

完整代码

package main

import (
	"crypto/ecdsa"
	"fmt"
	"log"

	"github.com/ethereum/go-ethereum/common/hexutil"
	"github.com/ethereum/go-ethereum/crypto"
	"golang.org/x/crypto/sha3"
)

func main() {
	//生成私钥
	privateKey, err := crypto.GenerateKey()
	if err != nil {
		log.Fatal(err)
	}

	//打印不含0x的私钥
	privateKeyBytes := crypto.FromECDSA(privateKey)
	fmt.Println(hexutil.Encode(privateKeyBytes)[2:]) // 4e6aaa173f18b6160aa6a36a4e54e4e79a5fff8a93d5efe5126c589f4464c052

	//根据私钥打印16进制公钥
	publicKey := privateKey.Public()
	publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
	if !ok {
		log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
	}

	publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA)
	fmt.Println(hexutil.Encode(publicKeyBytes)[4:]) // 405701f955192319aa5c0b9d7564cd0ff184a498dc12c5bda941c91354382dbf44ff6f1678ba3ea0bf9a545895c00ab7cfb2fbcf0c5cca97569a4bf0aed996c8

	//根据公钥返回地址
	address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()
	fmt.Println(address) // 0xe83FF792C385d6935d3b1f58c40de2BDEe3621e9

	//使用Keccak256函数手动完成地址解析
	hash := sha3.NewLegacyKeccak256()
	hash.Write(publicKeyBytes[1:])
	fmt.Println(hexutil.Encode(hash.Sum(nil)[12:])) // 0xe83ff792c385d6935d3b1f58c40de2bdee3621e9
}

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码

)">
< <上一篇
下一篇>>