Fixing Issues
This commit is contained in:
parent
ff408351a2
commit
0d2d55f839
|
@ -71,7 +71,7 @@ func CreateBlockchain(address, nodeID string) *Blockchain {
|
|||
// NewBlockchain creates a new Blockchain with genesis Block
|
||||
func NewBlockchain(nodeID string) *Blockchain {
|
||||
dbFile := fmt.Sprintf(dbFile, nodeID)
|
||||
if dbExists(dbFile) == false {
|
||||
if !dbExists(dbFile) {
|
||||
fmt.Println("No existing blockchain found. Create one first.")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
@ -81,7 +81,6 @@ func NewBlockchain(nodeID string) *Blockchain {
|
|||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
err = db.Update(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket([]byte(blocksBucket))
|
||||
tip = b.Get([]byte("l"))
|
||||
|
@ -140,7 +139,7 @@ func (bc *Blockchain) FindTransaction(ID []byte) (Transaction, error) {
|
|||
block := bci.Next()
|
||||
|
||||
for _, tx := range block.Transactions {
|
||||
if bytes.Compare(tx.ID, ID) == 0 {
|
||||
if bytes.Equal(tx.ID, ID) {
|
||||
return *tx, nil
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +180,7 @@ func (bc *Blockchain) FindUTXO() map[string]TXOutputs {
|
|||
UTXO[txID] = outs
|
||||
}
|
||||
|
||||
if tx.IsCoinbase() == false {
|
||||
if !tx.IsCoinbase() {
|
||||
for _, in := range tx.Vin {
|
||||
inTxID := hex.EncodeToString(in.Txid)
|
||||
spentTXOs[inTxID] = append(spentTXOs[inTxID], in.Vout)
|
||||
|
@ -233,7 +232,7 @@ func (bc *Blockchain) GetBlock(blockHash []byte) (Block, error) {
|
|||
blockData := b.Get(blockHash)
|
||||
|
||||
if blockData == nil {
|
||||
return errors.New("Block is not found.")
|
||||
return errors.New("Block not found ... ")
|
||||
}
|
||||
|
||||
block = *DeserializeBlock(blockData)
|
||||
|
@ -272,8 +271,9 @@ func (bc *Blockchain) MineBlock(transactions []*Transaction) *Block {
|
|||
|
||||
for _, tx := range transactions {
|
||||
// TODO: ignore transaction if it's not valid
|
||||
if bc.VerifyTransaction(tx) != true {
|
||||
log.Panic("ERROR: Invalid transaction")
|
||||
if !bc.VerifyTransaction(tx) {
|
||||
log.Println("ERROR: Invalid transaction passed to 'MineBlock'")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,7 +324,8 @@ func (bc *Blockchain) SignTransaction(tx *Transaction, privKey ecdsa.PrivateKey)
|
|||
for _, vin := range tx.Vin {
|
||||
prevTX, err := bc.FindTransaction(vin.Txid)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
log.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
prevTXs[hex.EncodeToString(prevTX.ID)] = prevTX
|
||||
}
|
||||
|
@ -343,7 +344,8 @@ func (bc *Blockchain) VerifyTransaction(tx *Transaction) bool {
|
|||
for _, vin := range tx.Vin {
|
||||
prevTX, err := bc.FindTransaction(vin.Txid)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
log.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
prevTXs[hex.EncodeToString(prevTX.ID)] = prevTX
|
||||
}
|
||||
|
|
|
@ -3,11 +3,13 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func (cli *CLI) createBlockchain(address, nodeID string) {
|
||||
if !ValidateAddress(address) {
|
||||
log.Panic("ERROR: Address is not valid")
|
||||
log.Println("ERROR: Address is not valid")
|
||||
os.Exit(1)
|
||||
}
|
||||
bc := CreateBlockchain(address, nodeID)
|
||||
defer bc.db.Close()
|
||||
|
|
|
@ -3,12 +3,15 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func (cli *CLI) getBalance(address, nodeID string) {
|
||||
if !ValidateAddress(address) {
|
||||
log.Panic("ERROR: Address is not valid")
|
||||
log.Println("ERROR: Address is not valid")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
bc := NewBlockchain(nodeID)
|
||||
UTXOSet := UTXOSet{bc}
|
||||
defer bc.db.Close()
|
||||
|
|
|
@ -13,6 +13,6 @@ func (cli *CLI) listAddresses(nodeID string) {
|
|||
addresses := wallets.GetAddresses()
|
||||
|
||||
for _, address := range addresses {
|
||||
fmt.Println(address)
|
||||
fmt.Printf("Address : %s\n", address)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ func (cli *CLI) printChain(nodeID string) {
|
|||
fmt.Printf("============ Block %x ============\n", block.Hash)
|
||||
fmt.Printf("Height: %d\n", block.Height)
|
||||
fmt.Printf("Prev. block: %x\n", block.PrevBlockHash)
|
||||
fmt.Printf("Merkle Root: %x\n", block.HashTransactions())
|
||||
pow := NewProofOfWork(block)
|
||||
fmt.Printf("PoW: %s\n\n", strconv.FormatBool(pow.Validate()))
|
||||
for _, tx := range block.Transactions {
|
||||
|
|
14
cli_send.go
14
cli_send.go
|
@ -3,16 +3,23 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func (cli *CLI) send(from, to string, amount int, nodeID string, mineNow bool) {
|
||||
if !ValidateAddress(from) {
|
||||
log.Panic("ERROR: Sender address is not valid")
|
||||
log.Println("ERROR: Sender address is not valid")
|
||||
os.Exit(1)
|
||||
}
|
||||
if !ValidateAddress(to) {
|
||||
log.Panic("ERROR: Recipient address is not valid")
|
||||
log.Println("ERROR: Recipient address is not valid")
|
||||
os.Exit(1)
|
||||
}
|
||||
if from == to {
|
||||
|
||||
log.Println("ERROR: Sender and Recipient cannot be same")
|
||||
os.Exit(1)
|
||||
}
|
||||
bc := NewBlockchain(nodeID)
|
||||
UTXOSet := UTXOSet{bc}
|
||||
defer bc.db.Close()
|
||||
|
@ -26,12 +33,15 @@ func (cli *CLI) send(from, to string, amount int, nodeID string, mineNow bool) {
|
|||
tx := NewUTXOTransaction(&wallet, to, amount, &UTXOSet)
|
||||
|
||||
if mineNow {
|
||||
|
||||
cbTx := NewCoinbaseTX(from, "")
|
||||
txs := []*Transaction{cbTx, tx}
|
||||
|
||||
newBlock := bc.MineBlock(txs)
|
||||
UTXOSet.Update(newBlock)
|
||||
|
||||
} else {
|
||||
|
||||
sendTx(knownNodes[0], tx)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
module blockchain_go
|
||||
|
||||
go 1.22.4
|
||||
|
||||
require (
|
||||
github.com/boltdb/bolt v1.3.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
golang.org/x/crypto v0.24.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
@ -51,14 +51,12 @@ func (pow *ProofOfWork) Run() (int, []byte) {
|
|||
var hash [32]byte
|
||||
nonce := 0
|
||||
|
||||
fmt.Printf("Mining a new block")
|
||||
fmt.Printf("Mining a new block ")
|
||||
|
||||
for nonce < maxNonce {
|
||||
data := pow.prepareData(nonce)
|
||||
|
||||
hash = sha256.Sum256(data)
|
||||
if math.Remainder(float64(nonce), 100000) == 0 {
|
||||
fmt.Printf("\r%x", hash)
|
||||
}
|
||||
|
||||
hashInt.SetBytes(hash[:])
|
||||
|
||||
if hashInt.Cmp(pow.target) == -1 {
|
||||
|
@ -67,8 +65,8 @@ func (pow *ProofOfWork) Run() (int, []byte) {
|
|||
nonce++
|
||||
}
|
||||
}
|
||||
fmt.Print("\n\n")
|
||||
|
||||
fmt.Printf("Nonce found: %d\n", nonce)
|
||||
return nonce, hash[:]
|
||||
}
|
||||
|
||||
|
|
|
@ -203,7 +203,7 @@ func handleBlock(request []byte, bc *Blockchain) {
|
|||
bc.AddBlock(block)
|
||||
|
||||
fmt.Printf("Added block %x\n", block.Hash)
|
||||
|
||||
fmt.Printf("Merkle root %x\n", block.HashTransactions())
|
||||
if len(blocksInTransit) > 0 {
|
||||
blockHash := blocksInTransit[0]
|
||||
sendGetData(payload.AddrFrom, "block", blockHash)
|
||||
|
@ -421,7 +421,9 @@ func handleConnection(conn net.Conn, bc *Blockchain) {
|
|||
func StartServer(nodeID, minerAddress string) {
|
||||
nodeAddress = fmt.Sprintf("localhost:%s", nodeID)
|
||||
miningAddress = minerAddress
|
||||
|
||||
ln, err := net.Listen(protocol, nodeAddress)
|
||||
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
@ -440,6 +442,7 @@ func StartServer(nodeID, minerAddress string) {
|
|||
}
|
||||
go handleConnection(conn, bc)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func gobEncode(data interface{}) []byte {
|
||||
|
|
|
@ -163,7 +163,7 @@ func (tx *Transaction) Verify(prevTXs map[string]Transaction) bool {
|
|||
dataToVerify := fmt.Sprintf("%x\n", txCopy)
|
||||
|
||||
rawPubKey := ecdsa.PublicKey{Curve: curve, X: &x, Y: &y}
|
||||
if ecdsa.Verify(&rawPubKey, []byte(dataToVerify), &r, &s) == false {
|
||||
if !ecdsa.Verify(&rawPubKey, []byte(dataToVerify), &r, &s) {
|
||||
return false
|
||||
}
|
||||
txCopy.Vin[inID].PubKey = nil
|
||||
|
@ -173,6 +173,7 @@ func (tx *Transaction) Verify(prevTXs map[string]Transaction) bool {
|
|||
}
|
||||
|
||||
// NewCoinbaseTX creates a new coinbase transaction
|
||||
|
||||
func NewCoinbaseTX(to, data string) *Transaction {
|
||||
if data == "" {
|
||||
randData := make([]byte, 20)
|
||||
|
@ -197,35 +198,43 @@ func NewUTXOTransaction(wallet *Wallet, to string, amount int, UTXOSet *UTXOSet)
|
|||
var inputs []TXInput
|
||||
var outputs []TXOutput
|
||||
|
||||
// Get the public key hash of the wallet
|
||||
pubKeyHash := HashPubKey(wallet.PublicKey)
|
||||
acc, validOutputs := UTXOSet.FindSpendableOutputs(pubKeyHash, amount)
|
||||
|
||||
// Find spendable outputs for the given amount
|
||||
acc, validOutputs := UTXOSet.FindSpendableOutputs(pubKeyHash, amount)
|
||||
if acc < amount {
|
||||
log.Panic("ERROR: Not enough funds")
|
||||
}
|
||||
|
||||
// Build a list of inputs
|
||||
// Build a list of inputs from the valid outputs
|
||||
for txid, outs := range validOutputs {
|
||||
txID, err := hex.DecodeString(txid)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
for _, out := range outs {
|
||||
input := TXInput{txID, out, nil, wallet.PublicKey}
|
||||
for _, outIndex := range outs {
|
||||
input := TXInput{txID, outIndex, nil, wallet.PublicKey}
|
||||
inputs = append(inputs, input)
|
||||
}
|
||||
}
|
||||
|
||||
// Build a list of outputs
|
||||
from := fmt.Sprintf("%s", wallet.GetAddress())
|
||||
// Create an output for the recipient
|
||||
outputs = append(outputs, *NewTXOutput(amount, to))
|
||||
|
||||
// Create a change output if there is any change
|
||||
|
||||
if acc > amount {
|
||||
outputs = append(outputs, *NewTXOutput(acc-amount, from)) // a change
|
||||
changeAddress := fmt.Sprintf("%s", wallet.GetAddress())
|
||||
outputs = append(outputs, *NewTXOutput(acc-amount, changeAddress)) // change output
|
||||
}
|
||||
|
||||
// Create the transaction
|
||||
tx := Transaction{nil, inputs, outputs}
|
||||
tx.ID = tx.Hash()
|
||||
|
||||
// Sign the transaction
|
||||
UTXOSet.Blockchain.SignTransaction(&tx, wallet.PrivateKey)
|
||||
|
||||
return &tx
|
||||
|
|
|
@ -14,5 +14,5 @@ type TXInput struct {
|
|||
func (in *TXInput) UsesKey(pubKeyHash []byte) bool {
|
||||
lockingHash := HashPubKey(in.PubKey)
|
||||
|
||||
return bytes.Compare(lockingHash, pubKeyHash) == 0
|
||||
return bytes.Equal(lockingHash, pubKeyHash)
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ func (out *TXOutput) Lock(address []byte) {
|
|||
|
||||
// IsLockedWithKey checks if the output can be used by the owner of the pubkey
|
||||
func (out *TXOutput) IsLockedWithKey(pubKeyHash []byte) bool {
|
||||
return bytes.Compare(out.PubKeyHash, pubKeyHash) == 0
|
||||
return bytes.Equal(out.PubKeyHash, pubKeyHash)
|
||||
}
|
||||
|
||||
// NewTXOutput create a new TXOutput
|
||||
|
|
35
utxo_set.go
35
utxo_set.go
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
|
@ -29,9 +30,16 @@ func (u UTXOSet) FindSpendableOutputs(pubkeyHash []byte, amount int) (int, map[s
|
|||
outs := DeserializeOutputs(v)
|
||||
|
||||
for outIdx, out := range outs.Outputs {
|
||||
if out.IsLockedWithKey(pubkeyHash) && accumulated < amount {
|
||||
accumulated += out.Value
|
||||
unspentOutputs[txID] = append(unspentOutputs[txID], outIdx)
|
||||
if out.IsLockedWithKey(pubkeyHash) {
|
||||
if accumulated < amount {
|
||||
accumulated += out.Value
|
||||
unspentOutputs[txID] = append(unspentOutputs[txID], outIdx)
|
||||
|
||||
// Early exit if the required amount is accumulated
|
||||
if accumulated >= amount {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +50,11 @@ func (u UTXOSet) FindSpendableOutputs(pubkeyHash []byte, amount int) (int, map[s
|
|||
log.Panic(err)
|
||||
}
|
||||
|
||||
// Check if we were able to accumulate the required amount
|
||||
if accumulated < amount {
|
||||
log.Printf("Warning: Unable to find enough spendable outputs. Needed %d, found %d", amount, accumulated)
|
||||
}
|
||||
|
||||
return accumulated, unspentOutputs
|
||||
}
|
||||
|
||||
|
@ -50,13 +63,20 @@ func (u UTXOSet) FindUTXO(pubKeyHash []byte) []TXOutput {
|
|||
var UTXOs []TXOutput
|
||||
db := u.Blockchain.db
|
||||
|
||||
// Read-only transaction to view the database
|
||||
err := db.View(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket([]byte(utxoBucket))
|
||||
if b == nil {
|
||||
return fmt.Errorf("Bucket %s not found!", utxoBucket)
|
||||
}
|
||||
|
||||
c := b.Cursor()
|
||||
|
||||
// Iterate through all keys in the bucket
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
outs := DeserializeOutputs(v)
|
||||
|
||||
// Filter outputs that are locked with the given public key hash
|
||||
for _, out := range outs.Outputs {
|
||||
if out.IsLockedWithKey(pubKeyHash) {
|
||||
UTXOs = append(UTXOs, out)
|
||||
|
@ -119,7 +139,7 @@ func (u UTXOSet) Reindex() {
|
|||
|
||||
UTXO := u.Blockchain.FindUTXO()
|
||||
|
||||
err = db.Update(func(tx *bolt.Tx) error {
|
||||
_ = db.Update(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(bucketName)
|
||||
|
||||
for txID, outs := range UTXO {
|
||||
|
@ -147,7 +167,7 @@ func (u UTXOSet) Update(block *Block) {
|
|||
b := tx.Bucket([]byte(utxoBucket))
|
||||
|
||||
for _, tx := range block.Transactions {
|
||||
if tx.IsCoinbase() == false {
|
||||
if !tx.IsCoinbase() {
|
||||
for _, vin := range tx.Vin {
|
||||
updatedOuts := TXOutputs{}
|
||||
outsBytes := b.Get(vin.Txid)
|
||||
|
@ -175,10 +195,7 @@ func (u UTXOSet) Update(block *Block) {
|
|||
}
|
||||
|
||||
newOutputs := TXOutputs{}
|
||||
for _, out := range tx.Vout {
|
||||
newOutputs.Outputs = append(newOutputs.Outputs, out)
|
||||
}
|
||||
|
||||
newOutputs.Outputs = append(newOutputs.Outputs, tx.Vout...)
|
||||
err := b.Put(tx.ID, newOutputs.Serialize())
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
|
|
86
wallet.go
86
wallet.go
|
@ -6,7 +6,10 @@ import (
|
|||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
)
|
||||
|
@ -63,7 +66,7 @@ func ValidateAddress(address string) bool {
|
|||
pubKeyHash = pubKeyHash[1 : len(pubKeyHash)-addressChecksumLen]
|
||||
targetChecksum := checksum(append([]byte{version}, pubKeyHash...))
|
||||
|
||||
return bytes.Compare(actualChecksum, targetChecksum) == 0
|
||||
return bytes.Equal(actualChecksum, targetChecksum)
|
||||
}
|
||||
|
||||
// Checksum generates a checksum for a public key
|
||||
|
@ -84,3 +87,84 @@ func newKeyPair() (ecdsa.PrivateKey, []byte) {
|
|||
|
||||
return *private, pubKey
|
||||
}
|
||||
func (w *Wallet) GobEncode() ([]byte, error) {
|
||||
var buffer bytes.Buffer
|
||||
encoder := gob.NewEncoder(&buffer)
|
||||
|
||||
// Encode the curve name
|
||||
curveName := "P256"
|
||||
if err := encoder.Encode(curveName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Encode the private key components
|
||||
privateKeyBytes := w.PrivateKey.D.Bytes()
|
||||
if err := encoder.Encode(privateKeyBytes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Encode the public key components
|
||||
xBytes := w.PrivateKey.PublicKey.X.Bytes()
|
||||
yBytes := w.PrivateKey.PublicKey.Y.Bytes()
|
||||
if err := encoder.Encode(xBytes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := encoder.Encode(yBytes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Encode the public key
|
||||
if err := encoder.Encode(w.PublicKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
func (w *Wallet) GobDecode(data []byte) error {
|
||||
buffer := bytes.NewBuffer(data)
|
||||
decoder := gob.NewDecoder(buffer)
|
||||
|
||||
// Decode the curve name
|
||||
var curveName string
|
||||
if err := decoder.Decode(&curveName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the curve based on the name
|
||||
var curve elliptic.Curve
|
||||
switch curveName {
|
||||
case "P256":
|
||||
curve = elliptic.P256()
|
||||
default:
|
||||
return fmt.Errorf("unsupported curve: %s", curveName)
|
||||
}
|
||||
|
||||
// Decode the private key components
|
||||
var privateKeyBytes []byte
|
||||
if err := decoder.Decode(&privateKeyBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.PrivateKey.PublicKey.Curve = curve
|
||||
w.PrivateKey.D = new(big.Int).SetBytes(privateKeyBytes)
|
||||
|
||||
// Decode the public key components
|
||||
var xBytes, yBytes []byte
|
||||
if err := decoder.Decode(&xBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := decoder.Decode(&yBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.PrivateKey.PublicKey.X = new(big.Int).SetBytes(xBytes)
|
||||
w.PrivateKey.PublicKey.Y = new(big.Int).SetBytes(yBytes)
|
||||
|
||||
// Decode the public key
|
||||
if err := decoder.Decode(&w.PublicKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
10
wallets.go
10
wallets.go
|
@ -66,7 +66,7 @@ func (ws *Wallets) LoadFromFile(nodeID string) error {
|
|||
}
|
||||
|
||||
var wallets Wallets
|
||||
gob.Register(elliptic.P256())
|
||||
//gob.Register(elliptic.P256())
|
||||
decoder := gob.NewDecoder(bytes.NewReader(fileContent))
|
||||
err = decoder.Decode(&wallets)
|
||||
if err != nil {
|
||||
|
@ -80,17 +80,25 @@ func (ws *Wallets) LoadFromFile(nodeID string) error {
|
|||
|
||||
// SaveToFile saves wallets to a file
|
||||
func (ws Wallets) SaveToFile(nodeID string) {
|
||||
// Create a buffer to hold the serialized data
|
||||
var content bytes.Buffer
|
||||
|
||||
// Format the filename using the nodeID
|
||||
walletFile := fmt.Sprintf(walletFile, nodeID)
|
||||
|
||||
// Register the elliptic curve with the gob package
|
||||
gob.Register(elliptic.P256())
|
||||
|
||||
// Create a new encoder that writes to the buffer
|
||||
encoder := gob.NewEncoder(&content)
|
||||
|
||||
// Encode the Wallets object into the buffer
|
||||
err := encoder.Encode(ws)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
// Write the buffer's content to the file
|
||||
err = ioutil.WriteFile(walletFile, content.Bytes(), 0644)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
|
|
Loading…
Reference in New Issue