Skip to content

Instantly share code, notes, and snippets.

@fangdingjun
Last active September 18, 2021 11:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fangdingjun/766f4978914a66c50074112bf8dd3c5f to your computer and use it in GitHub Desktop.
Save fangdingjun/766f4978914a66c50074112bf8dd3c5f to your computer and use it in GitHub Desktop.
golang: generate wallet address for multiple chain, base on the same private key, support ethereum, tron network, bitcoin, filecoin
package main
import (
"crypto/rand"
"crypto/sha256"
"encoding/base32"
"encoding/base64"
"encoding/hex"
"encoding/json"
"flag"
"fmt"
"os"
ec "crypto/elliptic"
base58check "github.com/anaskhan96/base58check"
secp "github.com/fomichev/secp256k1"
"golang.org/x/crypto/blake2b"
m160 "golang.org/x/crypto/ripemd160"
"golang.org/x/crypto/sha3"
)
func main() {
var p string
flag.StringVar(&p, "key", "", "from the specified private key")
flag.Parse()
var priv1 []byte
var err error
if p == "" {
priv1, _, _, err = ec.GenerateKey(secp.SECP256K1(), rand.Reader)
if err != nil {
fmt.Printf("generate private key failed: %s\n", err)
os.Exit(-1)
}
} else {
priv1, err = hex.DecodeString(p)
if err != nil {
fmt.Printf("invalid private key: %s\n", err)
os.Exit(-1)
}
}
fmt.Printf("private key(plain): %x\n", priv1)
// restore x, y from private key
crve := secp.SECP256K1()
x, y := crve.ScalarBaseMult(priv1)
pub := ec.Marshal(secp.SECP256K1(), x, y)
pub1 := ec.MarshalCompressed(secp.SECP256K1(), x, y)
fmt.Printf("public key(uncompress): %x\n", pub[1:])
fmt.Printf("public key(compressed): %x\n", pub1)
h := sha3.NewLegacyKeccak256()
h.Write(pub[1:])
_h := h.Sum(nil)
fmt.Printf("ethereum address: 0x%x\n", _h[len(_h)-20:])
t, _ := base58check.Encode("41", fmt.Sprintf("%x", _h[len(_h)-20:]))
fmt.Printf("tron address: %s\n", t)
// bitcoin legacy address
h2 := sha256.New()
h2.Write(pub1)
rip := m160.New()
rip.Write(h2.Sum(nil)[:])
_h2 := rip.Sum(nil)
t2, _ := base58check.Encode("00", fmt.Sprintf("%x", _h2))
fmt.Printf("bitcoin address: %s\n", t2)
// bitcoin segwit address
h2 = sha256.New()
h2.Write([]byte{0x00, 0x14})
h2.Write(_h2[:])
rip = m160.New()
rip.Write(h2.Sum(nil)[:])
_h2 = rip.Sum(nil)
t3, _ := base58check.Encode("05", fmt.Sprintf("%x", _h2))
fmt.Printf("bitcoin address(segwit): %s\n", t3)
k1, _ := base58check.Encode("80", fmt.Sprintf("%x01", priv1))
fmt.Printf("bitcoin private key(base58): %s\n", k1)
// filecoin address
b2b20, err := blake2b.New(20, nil)
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
b2b20.Write(pub)
payload := b2b20.Sum(nil)
b2b4, err := blake2b.New(4, nil)
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
b2b4.Write([]byte("\x01"))
b2b4.Write(payload)
chksum := b2b4.Sum(nil)
const encodeStd = "abcdefghijklmnopqrstuvwxyz234567"
b32 := base32.NewEncoding(encodeStd).WithPadding(base32.NoPadding)
buf := []byte("")
buf = append(buf, payload...)
buf = append(buf, chksum...)
a := b32.EncodeToString(buf)
fmt.Printf("filecoin address: f1%s\n", a)
pri := map[string]string{"Type": "secp256k1", "PrivateKey": base64.StdEncoding.EncodeToString(priv1)}
d1, _ := json.Marshal(pri)
fmt.Printf("filecoin private key(plain): %x\n", d1)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment