Clean up blockchain.go; improve TXInput and TXOutput
This commit is contained in:
parent
942120679b
commit
bb70b4924b
|
@ -30,15 +30,16 @@ func CreateBlockchain(address string) *Blockchain {
|
||||||
}
|
}
|
||||||
|
|
||||||
var tip []byte
|
var tip []byte
|
||||||
|
|
||||||
|
cbtx := NewCoinbaseTX(address, genesisCoinbaseData)
|
||||||
|
genesis := NewGenesisBlock(cbtx)
|
||||||
|
|
||||||
db, err := bolt.Open(dbFile, 0600, nil)
|
db, err := bolt.Open(dbFile, 0600, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.Update(func(tx *bolt.Tx) error {
|
err = db.Update(func(tx *bolt.Tx) error {
|
||||||
cbtx := NewCoinbaseTX(address, genesisCoinbaseData)
|
|
||||||
genesis := NewGenesisBlock(cbtx)
|
|
||||||
|
|
||||||
b, err := tx.CreateBucket([]byte(blocksBucket))
|
b, err := tx.CreateBucket([]byte(blocksBucket))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
|
@ -57,7 +58,6 @@ func CreateBlockchain(address string) *Blockchain {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,6 @@ func NewBlockchain(address string) *Blockchain {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
|
@ -107,7 +106,7 @@ Work:
|
||||||
txID := hex.EncodeToString(tx.ID)
|
txID := hex.EncodeToString(tx.ID)
|
||||||
|
|
||||||
for outIdx, out := range tx.Vout {
|
for outIdx, out := range tx.Vout {
|
||||||
if out.Unlock(pubKeyHash) && accumulated < amount {
|
if out.IsLockedWithKey(pubKeyHash) && accumulated < amount {
|
||||||
accumulated += out.Value
|
accumulated += out.Value
|
||||||
unspentOutputs[txID] = append(unspentOutputs[txID], outIdx)
|
unspentOutputs[txID] = append(unspentOutputs[txID], outIdx)
|
||||||
|
|
||||||
|
@ -158,21 +157,21 @@ func (bc *Blockchain) FindUnspentTransactions(pubKeyHash []byte) []Transaction {
|
||||||
for outIdx, out := range tx.Vout {
|
for outIdx, out := range tx.Vout {
|
||||||
// Was the output spent?
|
// Was the output spent?
|
||||||
if spentTXOs[txID] != nil {
|
if spentTXOs[txID] != nil {
|
||||||
for _, spentOut := range spentTXOs[txID] {
|
for _, spentOutIdx := range spentTXOs[txID] {
|
||||||
if spentOut == outIdx {
|
if spentOutIdx == outIdx {
|
||||||
continue Outputs
|
continue Outputs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if out.Unlock(pubKeyHash) {
|
if out.IsLockedWithKey(pubKeyHash) {
|
||||||
unspentTXs = append(unspentTXs, *tx)
|
unspentTXs = append(unspentTXs, *tx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if tx.IsCoinbase() == false {
|
if tx.IsCoinbase() == false {
|
||||||
for _, in := range tx.Vin {
|
for _, in := range tx.Vin {
|
||||||
if in.UnlocksOutputWith(pubKeyHash) {
|
if in.UsesKey(pubKeyHash) {
|
||||||
inTxID := hex.EncodeToString(in.Txid)
|
inTxID := hex.EncodeToString(in.Txid)
|
||||||
spentTXOs[inTxID] = append(spentTXOs[inTxID], in.Vout)
|
spentTXOs[inTxID] = append(spentTXOs[inTxID], in.Vout)
|
||||||
}
|
}
|
||||||
|
@ -195,7 +194,7 @@ func (bc *Blockchain) FindUTXO(pubKeyHash []byte) []TXOutput {
|
||||||
|
|
||||||
for _, tx := range unspentTransactions {
|
for _, tx := range unspentTransactions {
|
||||||
for _, out := range tx.Vout {
|
for _, out := range tx.Vout {
|
||||||
if out.Unlock(pubKeyHash) {
|
if out.IsLockedWithKey(pubKeyHash) {
|
||||||
UTXOs = append(UTXOs, out)
|
UTXOs = append(UTXOs, out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,6 +203,13 @@ func (bc *Blockchain) FindUTXO(pubKeyHash []byte) []TXOutput {
|
||||||
return UTXOs
|
return UTXOs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterator returns a BlockchainIterat
|
||||||
|
func (bc *Blockchain) Iterator() *BlockchainIterator {
|
||||||
|
bci := &BlockchainIterator{bc.tip, bc.db}
|
||||||
|
|
||||||
|
return bci
|
||||||
|
}
|
||||||
|
|
||||||
// MineBlock mines a new block with the provided transactions
|
// MineBlock mines a new block with the provided transactions
|
||||||
func (bc *Blockchain) MineBlock(transactions []*Transaction) {
|
func (bc *Blockchain) MineBlock(transactions []*Transaction) {
|
||||||
var lastHash []byte
|
var lastHash []byte
|
||||||
|
@ -220,7 +226,6 @@ func (bc *Blockchain) MineBlock(transactions []*Transaction) {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
|
@ -243,9 +248,12 @@ func (bc *Blockchain) MineBlock(transactions []*Transaction) {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignTransaction signs a Transaction
|
// SignTransaction signs inputs of a Transaction
|
||||||
func (bc *Blockchain) SignTransaction(tx *Transaction, privKey ecdsa.PrivateKey) {
|
func (bc *Blockchain) SignTransaction(tx *Transaction, privKey ecdsa.PrivateKey) {
|
||||||
prevTXs := make(map[string]Transaction)
|
prevTXs := make(map[string]Transaction)
|
||||||
|
|
||||||
|
@ -260,7 +268,7 @@ func (bc *Blockchain) SignTransaction(tx *Transaction, privKey ecdsa.PrivateKey)
|
||||||
tx.Sign(privKey, prevTXs)
|
tx.Sign(privKey, prevTXs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyTransaction verifies transaction
|
// VerifyTransaction verifies transaction input signatures
|
||||||
func (bc *Blockchain) VerifyTransaction(tx *Transaction) bool {
|
func (bc *Blockchain) VerifyTransaction(tx *Transaction) bool {
|
||||||
prevTXs := make(map[string]Transaction)
|
prevTXs := make(map[string]Transaction)
|
||||||
|
|
||||||
|
@ -272,22 +280,9 @@ func (bc *Blockchain) VerifyTransaction(tx *Transaction) bool {
|
||||||
prevTXs[hex.EncodeToString(prevTX.ID)] = prevTX
|
prevTXs[hex.EncodeToString(prevTX.ID)] = prevTX
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tx := range prevTXs {
|
|
||||||
fmt.Println(tx)
|
|
||||||
}
|
|
||||||
// fmt.Println()
|
|
||||||
// fmt.Println(tx)
|
|
||||||
|
|
||||||
return tx.Verify(prevTXs)
|
return tx.Verify(prevTXs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterator returns a BlockchainIterat
|
|
||||||
func (bc *Blockchain) Iterator() *BlockchainIterator {
|
|
||||||
bci := &BlockchainIterator{bc.tip, bc.db}
|
|
||||||
|
|
||||||
return bci
|
|
||||||
}
|
|
||||||
|
|
||||||
func dbExists() bool {
|
func dbExists() bool {
|
||||||
if _, err := os.Stat(dbFile); os.IsNotExist(err) {
|
if _, err := os.Stat(dbFile); os.IsNotExist(err) {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -9,8 +9,8 @@ type TXInput struct {
|
||||||
ScriptSig []byte
|
ScriptSig []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnlocksOutputWith checks whether the address initiated the transaction
|
// UsesKey checks whether the address initiated the transaction
|
||||||
func (in *TXInput) UnlocksOutputWith(pubKeyHash []byte) bool {
|
func (in *TXInput) UsesKey(pubKeyHash []byte) bool {
|
||||||
sigLen := 64
|
sigLen := 64
|
||||||
pubKey := in.ScriptSig[sigLen:]
|
pubKey := in.ScriptSig[sigLen:]
|
||||||
lockingHash := HashPubKey(pubKey)
|
lockingHash := HashPubKey(pubKey)
|
||||||
|
|
|
@ -15,8 +15,8 @@ func (out *TXOutput) Lock(address []byte) {
|
||||||
out.ScriptPubKey = pubKeyHash
|
out.ScriptPubKey = pubKeyHash
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock checks if the output can be used by the owner of the pubkey
|
// IsLockedWithKey checks if the output can be used by the owner of the pubkey
|
||||||
func (out *TXOutput) Unlock(pubKeyHash []byte) bool {
|
func (out *TXOutput) IsLockedWithKey(pubKeyHash []byte) bool {
|
||||||
return bytes.Compare(out.ScriptPubKey, pubKeyHash) == 0
|
return bytes.Compare(out.ScriptPubKey, pubKeyHash) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue