Implement address generation and wallets
This commit is contained in:
parent
373a09b2bc
commit
70c04fa8ce
|
@ -0,0 +1,66 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha256"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ripemd160"
|
||||||
|
)
|
||||||
|
|
||||||
|
const version = byte(0x00)
|
||||||
|
|
||||||
|
// Wallet ...
|
||||||
|
type Wallet struct {
|
||||||
|
PrivateKey []byte
|
||||||
|
PublicKey []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAddress returns wallet address
|
||||||
|
func (w Wallet) GetAddress() []byte {
|
||||||
|
publicSHA256 := sha256.Sum256(w.PublicKey)
|
||||||
|
|
||||||
|
RIPEMD160Hasher := ripemd160.New()
|
||||||
|
_, err := RIPEMD160Hasher.Write(publicSHA256[:])
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
publicRIPEMD160 := RIPEMD160Hasher.Sum(nil)
|
||||||
|
|
||||||
|
versionedPayload := append([]byte{version}, publicRIPEMD160...)
|
||||||
|
checksum := checksum(versionedPayload)
|
||||||
|
|
||||||
|
fullPayload := append(versionedPayload, checksum...)
|
||||||
|
address := Base58Encode(fullPayload)
|
||||||
|
|
||||||
|
return address
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWallet ...
|
||||||
|
func NewWallet() *Wallet {
|
||||||
|
private, public := newKeyPair()
|
||||||
|
wallet := Wallet{private, public}
|
||||||
|
|
||||||
|
return &wallet
|
||||||
|
}
|
||||||
|
|
||||||
|
func newKeyPair() ([]byte, []byte) {
|
||||||
|
curve := elliptic.P256()
|
||||||
|
private, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
public := append(x.Bytes(), y.Bytes()...)
|
||||||
|
|
||||||
|
return private, public
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checksum ...
|
||||||
|
func checksum(payload []byte) []byte {
|
||||||
|
firstSHA := sha256.Sum256(payload)
|
||||||
|
secondSHA := sha256.Sum256(firstSHA[:])
|
||||||
|
|
||||||
|
return secondSHA[:4]
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
var alphabet = []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
|
||||||
|
|
||||||
|
// Base58Encode encodes a byte array to Base58
|
||||||
|
func Base58Encode(input []byte) []byte {
|
||||||
|
var result []byte
|
||||||
|
|
||||||
|
x := big.NewInt(0)
|
||||||
|
x.SetBytes(input)
|
||||||
|
|
||||||
|
base := big.NewInt(int64(len(alphabet)))
|
||||||
|
zero := big.NewInt(0)
|
||||||
|
mod := &big.Int{}
|
||||||
|
|
||||||
|
for x.Cmp(zero) != 0 {
|
||||||
|
x.DivMod(x, base, mod)
|
||||||
|
result = append(result, alphabet[mod.Int64()])
|
||||||
|
}
|
||||||
|
|
||||||
|
ReverseBytes(result)
|
||||||
|
for c := range input {
|
||||||
|
if c == 0x00 {
|
||||||
|
result = append([]byte{alphabet[0]}, result...)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
15
cli.go
15
cli.go
|
@ -17,6 +17,11 @@ func (cli *CLI) createBlockchain(address string) {
|
||||||
fmt.Println("Done!")
|
fmt.Println("Done!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cli *CLI) createWallet() {
|
||||||
|
wallet := NewWallet()
|
||||||
|
fmt.Printf("Your address: %s\n", wallet.GetAddress())
|
||||||
|
}
|
||||||
|
|
||||||
func (cli *CLI) getBalance(address string) {
|
func (cli *CLI) getBalance(address string) {
|
||||||
bc := NewBlockchain(address)
|
bc := NewBlockchain(address)
|
||||||
defer bc.db.Close()
|
defer bc.db.Close()
|
||||||
|
@ -83,6 +88,7 @@ func (cli *CLI) Run() {
|
||||||
|
|
||||||
getBalanceCmd := flag.NewFlagSet("getbalance", flag.ExitOnError)
|
getBalanceCmd := flag.NewFlagSet("getbalance", flag.ExitOnError)
|
||||||
createBlockchainCmd := flag.NewFlagSet("createblockchain", flag.ExitOnError)
|
createBlockchainCmd := flag.NewFlagSet("createblockchain", flag.ExitOnError)
|
||||||
|
createWalletCmd := flag.NewFlagSet("createwallet", flag.ExitOnError)
|
||||||
sendCmd := flag.NewFlagSet("send", flag.ExitOnError)
|
sendCmd := flag.NewFlagSet("send", flag.ExitOnError)
|
||||||
printChainCmd := flag.NewFlagSet("printchain", flag.ExitOnError)
|
printChainCmd := flag.NewFlagSet("printchain", flag.ExitOnError)
|
||||||
|
|
||||||
|
@ -103,6 +109,11 @@ func (cli *CLI) Run() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
|
case "createwallet":
|
||||||
|
err := createWalletCmd.Parse(os.Args[2:])
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
case "printchain":
|
case "printchain":
|
||||||
err := printChainCmd.Parse(os.Args[2:])
|
err := printChainCmd.Parse(os.Args[2:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -134,6 +145,10 @@ func (cli *CLI) Run() {
|
||||||
cli.createBlockchain(*createBlockchainAddress)
|
cli.createBlockchain(*createBlockchainAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if createWalletCmd.Parsed() {
|
||||||
|
cli.createWallet()
|
||||||
|
}
|
||||||
|
|
||||||
if printChainCmd.Parsed() {
|
if printChainCmd.Parsed() {
|
||||||
cli.printChain()
|
cli.printChain()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue