77 "errors"
88 "fmt"
99 "github.com/dgraph-io/badger"
10+ "log"
1011 "os"
1112 "runtime"
1213)
@@ -98,13 +99,18 @@ func ContinueBlockChain(address string) *BlockChain {
9899 return & chain
99100}
100101
101- func (chain * BlockChain ) AddBlock (transactions []* Transaction ) {
102+ func (chain * BlockChain ) AddBlock (transactions []* Transaction ) * Block {
102103 var lastHash []byte
103104
105+ for _ , tx := range transactions {
106+ if chain .VerifyTransaction (tx ) != true {
107+ log .Panic ("Invalid Transaction" )
108+ }
109+ }
110+
104111 err := chain .Database .View (func (txn * badger.Txn ) error {
105112 item , err := txn .Get ([]byte ("lh" ))
106113 Handle (err )
107-
108114 err = item .Value (func (val []byte ) error {
109115 lastHash = val
110116 return nil
@@ -126,6 +132,8 @@ func (chain *BlockChain) AddBlock(transactions []*Transaction) {
126132 return err
127133 })
128134 Handle (err )
135+
136+ return newBlock
129137}
130138
131139func (chain * BlockChain ) Iterator () * ChainIterator {
@@ -155,6 +163,46 @@ func (iter *ChainIterator) Next() *Block {
155163 return block
156164}
157165
166+ func (chain * BlockChain ) FindUTXO () map [string ]TxOutputs {
167+ UTXO := make (map [string ]TxOutputs )
168+ spentTXOs := make (map [string ][]int )
169+
170+ iter := chain .Iterator ()
171+
172+ for {
173+ block := iter .Next ()
174+
175+ for _ , tx := range block .Transactions {
176+ txID := hex .EncodeToString (tx .ID )
177+
178+ Outputs:
179+ for outIdx , out := range tx .Outputs {
180+ if spentTXOs [txID ] != nil {
181+ for _ , spentOut := range spentTXOs [txID ] {
182+ if spentOut == outIdx {
183+ continue Outputs
184+ }
185+ }
186+ }
187+ outs := UTXO [txID ]
188+ outs .Outputs = append (outs .Outputs , out )
189+ UTXO [txID ] = outs
190+ }
191+ if tx .IsCoinbase () == false {
192+ for _ , in := range tx .Inputs {
193+ inTxID := hex .EncodeToString (in .ID )
194+ spentTXOs [inTxID ] = append (spentTXOs [inTxID ], in .Out )
195+ }
196+ }
197+ }
198+
199+ if len (block .PrevHash ) == 0 {
200+ break
201+ }
202+ }
203+ return UTXO
204+ }
205+
158206func (chain * BlockChain ) FindUnspentTransactions (pubKeyHash []byte ) []Transaction {
159207 var unspentTxs []Transaction
160208
@@ -181,7 +229,7 @@ func (chain *BlockChain) FindUnspentTransactions(pubKeyHash []byte) []Transactio
181229 unspentTxs = append (unspentTxs , * tx )
182230 }
183231 }
184- if tx .isCoinbase () == false {
232+ if tx .IsCoinbase () == false {
185233 for _ , in := range tx .Inputs {
186234 if in .UsesKey (pubKeyHash ) {
187235 inTxID := hex .EncodeToString (in .ID )
@@ -198,20 +246,6 @@ func (chain *BlockChain) FindUnspentTransactions(pubKeyHash []byte) []Transactio
198246 return unspentTxs
199247}
200248
201- func (chain * BlockChain ) FindUTXO (pubKeyHash []byte ) []TxOutput {
202- var UTXOs []TxOutput
203- unspentTransactions := chain .FindUnspentTransactions (pubKeyHash )
204-
205- for _ , tx := range unspentTransactions {
206- for _ , out := range tx .Outputs {
207- if out .IsLockedWithKey (pubKeyHash ) {
208- UTXOs = append (UTXOs , out )
209- }
210- }
211- }
212- return UTXOs
213- }
214-
215249func (chain * BlockChain ) FindSpendableOutputs (pubKeyHash []byte , amount int ) (int , map [string ][]int ) {
216250 unspentOuts := make (map [string ][]int )
217251 unspentTxs := chain .FindUnspentTransactions (pubKeyHash )
@@ -236,8 +270,8 @@ Work:
236270 return accumulated , unspentOuts
237271}
238272
239- func (bc * BlockChain ) FindTransaction (ID []byte ) (Transaction , error ) {
240- iter := bc .Iterator ()
273+ func (chain * BlockChain ) FindTransaction (ID []byte ) (Transaction , error ) {
274+ iter := chain .Iterator ()
241275
242276 for {
243277 block := iter .Next ()
@@ -256,23 +290,23 @@ func (bc *BlockChain) FindTransaction(ID []byte) (Transaction, error) {
256290 return Transaction {}, errors .New ("Transaction does not exist" )
257291}
258292
259- func (bc * BlockChain ) SignTransaction (tx * Transaction , privKey ecdsa.PrivateKey ) {
293+ func (chain * BlockChain ) SignTransaction (tx * Transaction , privKey ecdsa.PrivateKey ) {
260294 prevTXs := make (map [string ]Transaction )
261295
262296 for _ , in := range tx .Inputs {
263- prevTX , err := bc .FindTransaction (in .ID )
297+ prevTX , err := chain .FindTransaction (in .ID )
264298 Handle (err )
265299 prevTXs [hex .EncodeToString (prevTX .ID )] = prevTX
266300 }
267301
268302 tx .Sign (privKey , prevTXs )
269303}
270304
271- func (bc * BlockChain ) VerifyTransaction (tx * Transaction ) bool {
305+ func (chain * BlockChain ) VerifyTransaction (tx * Transaction ) bool {
272306 prevTXs := make (map [string ]Transaction )
273307
274308 for _ , in := range tx .Inputs {
275- prevTX , err := bc .FindTransaction (in .ID )
309+ prevTX , err := chain .FindTransaction (in .ID )
276310 Handle (err )
277311 prevTXs [hex .EncodeToString (prevTX .ID )] = prevTX
278312 }
0 commit comments