以太坊 地址生成算法

以太坊地址类似银行账号,通过该地址可以进行发送、接收以太坊,查询交易或者余额信息等。以太坊地址的表现形式是一串十六进制的数字,它从公钥的 Keccak256 哈希值的最后20个字节导出的标识符。

1. 以太坊地址生成过程

  • 生成 256 位随机数作为私钥。
  • 将私钥转化为 secp256k1 非压缩格式的公钥,即 512 位的公钥。
  • 使用散列算法 Keccak256 计算公钥的哈希值,转化为十六进制字符串。
  • 取十六进制字符串的后 40 个字母,开头加上 0x 作为地址。

2. 以太坊地址生成示例

package main
import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"fmt"
	"crypto/rand"

	"golang.org/x/crypto/sha3"
	"github.com/ethereum/go-ethereum/crypto/secp256k1"
)
type KeccakState interface {
	Write(p []byte) (n int, err error)
	Read([]byte) (int, error)
}

func Keccak256(data ...[]byte) []byte {
	b := make([]byte, 32)
	d := sha3.NewLegacyKeccak256().(KeccakState)
	for _, b := range data {
		d.Write(b)
	}
	d.Read(b)
	return b
}

func PubkeyToAddress(p ecdsa.PublicKey) string {
	pubBytes := elliptic.Marshal(secp256k1.S256(), p.X, p.Y)
	return fmt.Sprintf("0x%x", Keccak256(pubBytes[1:])[12:])
}

func main() {
	privateKeyECDSA, _ := ecdsa.GenerateKey(secp256k1.S256(), rand.Reader)
	fmt.Println(PubkeyToAddress(privateKeyECDSA.PublicKey))
}

输出结果:

0x310ea38c411754583a87417be91ca235f3cb005c

Geth 在创建账号时会生成一个对应 keystore JSON 文件,Keystore 文件存储加密后的私钥信息,因此我们需要做的就是导入这个 Keystore 文件,这个文件通常在同步区块数据的目录下的 k ...