1 package blockchain
2 3 import (
4 "github.com/p9c/p9/pkg/btcaddr"
5 "github.com/p9c/p9/pkg/fork"
6 "github.com/p9c/p9/pkg/txscript"
7 "github.com/p9c/p9/pkg/util"
8 )
9 10 // ContainsBlacklisted returns true if one of the given addresses is found in the transaction
11 func ContainsBlacklisted(b *BlockChain, tx *util.Tx, blacklist []btcaddr.Address) (hasBlacklisted bool) {
12 // in tests this function is not relevant
13 if b == nil {
14 return false
15 }
16 // blacklist only applies from hard fork
17 if fork.GetCurrent(b.BestSnapshot().Height) < 1 {
18 return false
19 }
20 var addrs []btcaddr.Address
21 // first decode transaction and collect all addresses in the transaction outputs
22 txo := tx.MsgTx().TxOut
23 for i := range txo {
24 script := txo[i].PkScript
25 _, a, _, _ := txscript.ExtractPkScriptAddrs(script, b.params)
26 addrs = append(addrs, a...)
27 }
28 // next get the addresses from the input transactions outpoints
29 txi := tx.MsgTx().TxIn
30 for i := range txi {
31 bb, e := b.BlockByHash(&txi[i].PreviousOutPoint.Hash)
32 if e == nil {
33 txs := bb.WireBlock().Transactions
34 for j := range txs {
35 txitxo := txs[j].TxOut
36 for k := range txitxo {
37 script := txitxo[k].PkScript
38 _, a, _, _ := txscript.ExtractPkScriptAddrs(script, b.params)
39 addrs = append(addrs, a...)
40 }
41 }
42 }
43 }
44 // check if the set of addresses intersects with the blacklist
45 return Intersects(addrs, blacklist)
46 }
47 48 // Intersects returns whether one slice of byte slices contains a match in another
49 func Intersects(a, b []btcaddr.Address) bool {
50 for x := range a {
51 for y := range b {
52 if a[x].EncodeAddress() == b[y].EncodeAddress() {
53 // If we find one match the two arrays intersect
54 return true
55 }
56 }
57 }
58 return false
59 }
60