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!")
|
||||
}
|
||||
|
||||
func (cli *CLI) createWallet() {
|
||||
wallet := NewWallet()
|
||||
fmt.Printf("Your address: %s\n", wallet.GetAddress())
|
||||
}
|
||||
|
||||
func (cli *CLI) getBalance(address string) {
|
||||
bc := NewBlockchain(address)
|
||||
defer bc.db.Close()
|
||||
|
@ -83,6 +88,7 @@ func (cli *CLI) Run() {
|
|||
|
||||
getBalanceCmd := flag.NewFlagSet("getbalance", flag.ExitOnError)
|
||||
createBlockchainCmd := flag.NewFlagSet("createblockchain", flag.ExitOnError)
|
||||
createWalletCmd := flag.NewFlagSet("createwallet", flag.ExitOnError)
|
||||
sendCmd := flag.NewFlagSet("send", flag.ExitOnError)
|
||||
printChainCmd := flag.NewFlagSet("printchain", flag.ExitOnError)
|
||||
|
||||
|
@ -103,6 +109,11 @@ func (cli *CLI) Run() {
|
|||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
case "createwallet":
|
||||
err := createWalletCmd.Parse(os.Args[2:])
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
case "printchain":
|
||||
err := printChainCmd.Parse(os.Args[2:])
|
||||
if err != nil {
|
||||
|
@ -134,6 +145,10 @@ func (cli *CLI) Run() {
|
|||
cli.createBlockchain(*createBlockchainAddress)
|
||||
}
|
||||
|
||||
if createWalletCmd.Parsed() {
|
||||
cli.createWallet()
|
||||
}
|
||||
|
||||
if printChainCmd.Parsed() {
|
||||
cli.printChain()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue