Browse Source

Allow creation of Account without knowing the seed

xno
codesoap 9 months ago
parent
commit
898697d115
  1. 26
      account.go
  2. 36
      cmd/atto/main.go
  3. 12
      cmd/atto/util.go
  4. 11
      util.go

26
account.go

@ -18,11 +18,10 @@ var ErrAccountNotFound = fmt.Errorf("account has not yet been opened") @@ -18,11 +18,10 @@ var ErrAccountNotFound = fmt.Errorf("account has not yet been opened")
// manipulated. This probably means someone is trying to steal funds.
var ErrAccountManipulated = fmt.Errorf("the received account info has been manipulated")
// Account holds the keys and address of a Nano account.
// Account holds the public key and address of a Nano account.
type Account struct {
PrivateKey *big.Int
PublicKey *big.Int
Address string
PublicKey *big.Int
Address string
}
type blockInfo struct {
@ -30,20 +29,19 @@ type blockInfo struct { @@ -30,20 +29,19 @@ type blockInfo struct {
Contents Block `json:"contents"`
}
// NewAccount creates a new Account and populates all its fields.
func NewAccount(seed *big.Int, index uint32) (a Account, err error) {
a.PrivateKey = getPrivateKey(seed, index)
a.PublicKey = derivePublicKey(a.PrivateKey)
// NewAccount creates a new Account and populates both its fields.
func NewAccount(privateKey *big.Int) (a Account, err error) {
a.PublicKey = derivePublicKey(privateKey)
a.Address, err = getAddress(a.PublicKey)
return
}
func getPrivateKey(seed *big.Int, index uint32) *big.Int {
seedBytes := bigIntToBytes(seed, 32)
indexBytes := bigIntToBytes(big.NewInt(int64(index)), 4)
in := append(seedBytes, indexBytes...)
privateKeyBytes := blake2b.Sum256(in)
return big.NewInt(0).SetBytes(privateKeyBytes[:])
// NewAccountFromAddress creates a new Account and populates both its
// fields.
func NewAccountFromAddress(address string) (a Account, err error) {
a.Address = address
a.PublicKey, err = getPublicKeyFromAddress(address)
return
}
func derivePublicKey(privateKey *big.Int) *big.Int {

36
cmd/atto/main.go

@ -6,6 +6,8 @@ import ( @@ -6,6 +6,8 @@ import (
"fmt"
"math/big"
"os"
"github.com/codesoap/atto"
)
var usage = `Usage:
@ -102,7 +104,12 @@ func printNewSeed() error { @@ -102,7 +104,12 @@ func printNewSeed() error {
}
func printAddress() error {
account, err := ownAccount()
seed, err := getSeed()
if err != nil {
return err
}
privateKey := atto.NewPrivateKey(seed, uint32(accountIndexFlag))
account, err := atto.NewAccount(privateKey)
if err == nil {
fmt.Println(account.Address)
}
@ -110,7 +117,12 @@ func printAddress() error { @@ -110,7 +117,12 @@ func printAddress() error {
}
func printBalance() error {
account, err := ownAccount()
seed, err := getSeed()
if err != nil {
return err
}
privateKey := atto.NewPrivateKey(seed, uint32(accountIndexFlag))
account, err := atto.NewAccount(privateKey)
if err != nil {
return err
}
@ -133,7 +145,7 @@ func printBalance() error { @@ -133,7 +145,7 @@ func printBalance() error {
if err != nil {
return err
}
if err = block.Sign(account.PublicKey, account.PrivateKey); err != nil {
if err = block.Sign(account.PublicKey, privateKey); err != nil {
return err
}
if err = block.FetchWork(sendWorkThreshold, account.PublicKey, node); err != nil {
@ -154,7 +166,12 @@ func printBalance() error { @@ -154,7 +166,12 @@ func printBalance() error {
func changeRepresentative() error {
representative := flag.Arg(1)
account, err := ownAccount()
seed, err := getSeed()
if err != nil {
return err
}
privateKey := atto.NewPrivateKey(seed, uint32(accountIndexFlag))
account, err := atto.NewAccount(privateKey)
if err != nil {
return err
}
@ -168,7 +185,7 @@ func changeRepresentative() error { @@ -168,7 +185,7 @@ func changeRepresentative() error {
if err != nil {
return err
}
if err = block.Sign(account.PublicKey, account.PrivateKey); err != nil {
if err = block.Sign(account.PublicKey, privateKey); err != nil {
return err
}
if err = block.FetchWork(sendWorkThreshold, account.PublicKey, node); err != nil {
@ -184,7 +201,12 @@ func changeRepresentative() error { @@ -184,7 +201,12 @@ func changeRepresentative() error {
func sendFunds() error {
amount := flag.Arg(1)
recipient := flag.Arg(2)
account, err := ownAccount()
seed, err := getSeed()
if err != nil {
return err
}
privateKey := atto.NewPrivateKey(seed, uint32(accountIndexFlag))
account, err := atto.NewAccount(privateKey)
if err != nil {
return err
}
@ -201,7 +223,7 @@ func sendFunds() error { @@ -201,7 +223,7 @@ func sendFunds() error {
if err != nil {
return err
}
if err = block.Sign(account.PublicKey, account.PrivateKey); err != nil {
if err = block.Sign(account.PublicKey, privateKey); err != nil {
return err
}
if err = block.FetchWork(sendWorkThreshold, account.PublicKey, node); err != nil {

12
cmd/atto/util.go

@ -7,20 +7,8 @@ import ( @@ -7,20 +7,8 @@ import (
"os"
"runtime"
"strings"
"github.com/codesoap/atto"
)
// ownAccount initializes the own account using the seed provided via
// standard input and accountIndexFlag.
func ownAccount() (atto.Account, error) {
seed, err := getSeed()
if err != nil {
return atto.Account{}, err
}
return atto.NewAccount(seed, uint32(accountIndexFlag))
}
// getSeed takes the first line of the standard input and interprets it
// as a hexadecimal representation of a 32byte seed.
func getSeed() (*big.Int, error) {

11
util.go

@ -6,8 +6,19 @@ import ( @@ -6,8 +6,19 @@ import (
"math/big"
"net/http"
"strings"
"golang.org/x/crypto/blake2b"
)
// NewPrivateKey creates a private key from the given seed and index.
func NewPrivateKey(seed *big.Int, index uint32) *big.Int {
seedBytes := bigIntToBytes(seed, 32)
indexBytes := bigIntToBytes(big.NewInt(int64(index)), 4)
in := append(seedBytes, indexBytes...)
privateKeyBytes := blake2b.Sum256(in)
return big.NewInt(0).SetBytes(privateKeyBytes[:])
}
func base32Encode(in *big.Int) string {
alphabet := []byte("13456789abcdefghijkmnopqrstuwxyz")
bigZero := big.NewInt(0)

Loading…
Cancel
Save