Skip to content

Commit

Permalink
Document exports
Browse files Browse the repository at this point in the history
Implement Marshal for everythign that needs it
Implement encoding/decoding of blocks
  • Loading branch information
jordanschalm committed May 9, 2017
1 parent 4ca1ad4 commit b39465a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 52 deletions.
45 changes: 38 additions & 7 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,38 @@ package blockchain
import (
"crypto/sha256"
"encoding/binary"
"encoding/gob"
"io"
)

// Hash represents a hash of a block or transaction
type Hash [32]byte

// BlockHeader contains metadata about a block
type BlockHeader struct {
blockNumber uint32
lastBlock Hash
miner Wallet
}

// Marshal converts a BlockHeader to a byte slice
func (bh *BlockHeader) Marshal() []byte {
buf := []byte{}
binary.LittleEndian.PutUint32(buf, bh.blockNumber)
buf = append(buf, bh.lastBlock...)
for _, b := range bh.lastBlock {
buf = append(buf, b)
}
buf = append(buf, bh.miner.Marshal()...)
return buf
}

// Block represents a block in the blockchain. Contains transactions and header metadata.
type Block struct {
BlockHeader
transactions []Transaction
transactions []*Transaction
}

// Marshal converts a Block to a byte slice
func (b *Block) Marshal() []byte {
buf := b.BlockHeader.Marshal()
for _, t := range b.transactions {
Expand All @@ -32,13 +43,33 @@ func (b *Block) Marshal() []byte {
return buf
}

func (b *Block) Hash() []byte {
sum := sha256.Sum256(b.Marshal())
return sum[:]
// Encode writes the marshalled block to the given io.Writer
func (b *Block) Encode(w io.Writer) {
gob.NewEncoder(w).Encode(b)
}

// Encode reads the marshalled block from the given io.Reader
func (b *Block) Decode(r io.Reader) {
gob.NewDecoder(r).Decode(b)
}

type BlockChain []Block
// Hash computes and returns the SHA256 hash of the block
func (b *Block) Hash() Hash {
return sha256.Sum256(b.Marshal())
}

// BlockChain represents a linked list of blocks
type BlockChain struct {
blocks []*Block
head Hash
}

func (bc BlockChain) Verify(b *Block) {
// Encode writes the marshalled blockchain to the given io.Writer
func (b *BlockChain) Encode(w io.Writer) {
gob.NewEncoder(w).Encode(b)
}

// Encode reads the marshalled blockchain from the given io.Reader
func (b *BlockChain) Decode(r io.Reader) {
gob.NewDecoder(r).Decode(b)
}
34 changes: 18 additions & 16 deletions blockchain/transaction.go
Original file line number Diff line number Diff line change
@@ -1,36 +1,35 @@
package blockchain

import (
"encoding/binary"
)
import "encoding/binary"

// TxHashPointer is a reference to a transaction on the blockchain.
type TxHashPointer struct {
blockNumber uint32
hash []byte
hash Hash
}

// Marshal converts a TxHashPointer to a byte slice
func (thp TxHashPointer) Marshal() []byte {
buf := []byte{}
binary.LittleEndian.PutUint32(buf, thp.blockNumber)
return append(buf, thp.hash...)
for _, b := range thp.hash {
buf = append(buf, b)
}
return buf
}

// TxBody contains all relevant information about a transaction.
type TxBody struct {
sender Wallet
inputs []TxHashPointer
outputs []TxHashPointer
sender Wallet
input TxHashPointer
output TxHashPointer
}

func (tb *TxBody) Marshal() []byte {
// Marshal converts a TxBody to a byte slice
func (tb TxBody) Marshal() []byte {
buf := tb.sender.Marshal()
for _, input := range tb.inputs {
buf = append(buf, input.Marshal()...)
}
for _, output := range tb.outputs {
buf = append(buf, output.Marshal()...)
}
buf = append(buf, tb.input.Marshal()...)
buf = append(buf, tb.output.Marshal()...)
return buf
}

Expand All @@ -41,9 +40,12 @@ type Transaction struct {
sig Signature
}

// Marshal converts a Transaction to a byte slice
func (t *Transaction) Marshal() []byte {
buf := t.TxBody.Marshal()
buf = append(buf, t.hash...)
for _, b := range t.hash {
buf = append(buf, b)
}
buf = append(buf, t.sig.X.Bytes()...)
buf = append(buf, t.sig.Y.Bytes()...)
return buf
Expand Down
14 changes: 5 additions & 9 deletions blockchain/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,20 @@ import (
"math/big"
)

// The curve we use for our ECC crypto.
var curve = elliptic.P256()

// Wallet represents a Cumulus wallet address in the blockchain.
type Wallet ecdsa.PublicKey

// Hash represents a hash of a transaction.
type Hash []byte

// Signature represents a signature of a transaction.
type Signature struct {
X big.Int
Y big.Int
}

// New creates a new Wallet backed by a ECC key pair. Uses system entropy.
func NewWallet() (*Wallet, error) {
func newWallet() (*Wallet, error) {
k, err := ecdsa.GenerateKey(curve, rand.Reader)
if err != nil {
return nil, err
Expand All @@ -32,19 +30,17 @@ func NewWallet() (*Wallet, error) {
return &pk, nil
}

// String returns a human-readable string representation of a wallet
func (w *Wallet) String() string {
return fmt.Sprintf("%x-%x", w.X, w.Y)
}

// Marshal converts the Wallet to a byte slice
func (w *Wallet) Marshal() []byte {
return elliptic.Marshal(curve, w.X, w.Y)
}

// Equals checks whether two wallets are the same.
func (w *Wallet) Equals(other *Wallet) bool {
return w.X.Cmp(other.X) == 0 && w.Y.Cmp(other.Y) == 0
}

func Unmarshal(wallet []byte) *Wallet {
x, y := elliptic.Unmarshal(curve, wallet)
return &Wallet{curve, x, y}
}
20 changes: 0 additions & 20 deletions blockchain/wallet_test.go

This file was deleted.

0 comments on commit b39465a

Please sign in to comment.