Last active
September 18, 2021 11:15
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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