-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTransaction.hs
More file actions
77 lines (60 loc) · 2.23 KB
/
Transaction.hs
File metadata and controls
77 lines (60 loc) · 2.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
{-# LANGUAGE OverloadedStrings, RecordWildCards #-}
module Transaction where
import Crypto
import Address
import Data.ByteString (ByteString)
import Data.ByteString.Char8 hiding (foldl')
import Data.List
import Data.Maybe
import Data.Time.Clock.POSIX
data Transaction = Transaction {
header :: TransactionHeader,
input :: ByteString,
output :: ByteString,
amount :: Int
} deriving (Eq, Show, Read)
data TransactionHeader = TransactionHeader {
txTime :: Int,
txSign :: Signature
} deriving (Eq, Show, Read)
transfer :: Address -> ByteString -> Int -> IO (Maybe Transaction)
transfer sender recvAddr amount
| amount > (balance sender) = do
print "Invalid Transaction"
return Nothing
| otherwise = do
timestamp <- now
let data_ = hash . append (hexAddr sender) . append recvAddr $ showBS amount
sign_ <- sign (snd $ keyPair sender) data_
let head_ = TransactionHeader timestamp sign_
return . Just $ Transaction head_ (hexAddr sender) recvAddr amount
expand_pool :: Transaction -> [Transaction] -> [Transaction]
expand_pool tx pool = if verify_tx tx then tx : pool else pool
reduce_pool :: [Transaction] -> [Transaction] -> [Transaction]
reduce_pool txs pool = pool \\ txs
-- | Verify a Signed Trasaction from given signature and data
verify_tx :: Transaction -> Bool
verify_tx tx = verify (fromJust . getPubKey_ $ input tx) (txSign $ header tx) (hash_tx tx)
-- | Verify a batch of Transactions
verify_txs :: [Transaction] -> Bool
verify_txs txs = foldl' (&&) True (verify_tx <$> txs)
-- | Hash transaction data with SHA256
hash_tx :: Transaction -> Digest SHA256
hash_tx Transaction{..} = hash . append input $ append output (showBS amount)
-- | Hash transaction data with SHA256, in Bytestring form
hash_tx' :: Transaction -> ByteString
hash_tx' = showBS . hash_tx
hash_id :: Transaction -> ByteString
hash_id = showBS . hash . showBS
-- | Current time in millisecond
now :: IO Int
now = round <$> (*1000) <$> getPOSIXTime
-- | Number of transactions
size :: [ByteString] -> Int
size = Data.List.length
-- | Show ByteString
showBS :: Show a => a -> ByteString
showBS = pack . show
-- | Read ByteString
readBS :: Read a => ByteString -> a
readBS = read . unpack