生成以太坊系地址

代码解析

要首先生成一个新的钱包地址,我们需要导入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
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰哥的技术杂货铺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值