{-# LANGUAGE OverloadedStrings #-} module Blockchain.Data.Transaction ( Transaction(..), codeOrDataLength, zeroBytesLength ) where import qualified Data.ByteString as B import Text.PrettyPrint.ANSI.Leijen import Blockchain.Data.Address import Blockchain.VM.Code import qualified Blockchain.Colors as CL import Blockchain.Format import Blockchain.Data.RLP import Blockchain.Util --import VM --import Debug.Trace data Transaction = MessageTX { tNonce::Integer, gasPrice::Integer, tGasLimit::Integer, to::Address, value::Integer, tData::B.ByteString } | ContractCreationTX { tNonce::Integer, gasPrice::Integer, tGasLimit::Integer, value::Integer, tInit::Code } deriving (Show) instance Format Transaction where format MessageTX{tNonce=n, gasPrice=gp, tGasLimit=gl, to=to', value=v, tData=d} = CL.blue "Message Transaction" ++ tab ( "\n" ++ "tNonce: " ++ show n ++ "\n" ++ "gasPrice: " ++ show gp ++ "\n" ++ "tGasLimit: " ++ show gl ++ "\n" ++ "to: " ++ show (pretty to') ++ "\n" ++ "value: " ++ show v ++ "\n" ++ "tData: " ++ tab ("\n" ++ format d) ++ "\n") format ContractCreationTX{tNonce=n, gasPrice=gp, tGasLimit=gl, value=v, tInit=init'} = CL.blue "Contract Creation Transaction" ++ tab ( "\n" ++ "tNonce: " ++ show n ++ "\n" ++ "gasPrice: " ++ show gp ++ "\n" ++ "tGasLimit: " ++ show gl ++ "\n" ++ "value: " ++ show v ++ "\n" ++ "tInit: " ++ tab ("\n" ++ show (pretty init')) ++ "\n") instance RLPSerializable Transaction where rlpDecode (RLPArray [n, gp, gl, RLPString "", val, i]) = --rlpDecode (RLPArray [n, gp, gl, toAddr, val, i]) | rlpDecode toAddr == (0::Integer) && not (null $ (rlpDecode i::String)) = ContractCreationTX { tNonce = rlpDecode n, gasPrice = rlpDecode gp, tGasLimit = rlpDecode gl, value = rlpDecode val, tInit = rlpDecode i } rlpDecode (RLPArray [n, gp, gl, toAddr, val, i]) = MessageTX { tNonce = rlpDecode n, gasPrice = rlpDecode gp, tGasLimit = rlpDecode gl, to = rlpDecode toAddr, value = rlpDecode val, tData = rlpDecode i } rlpDecode x = error ("rlpDecode for Transaction called on non block object: " ++ show x) rlpEncode MessageTX{tNonce=n, gasPrice=gp, tGasLimit=gl, to=to', value=v, tData=d} = RLPArray [ rlpEncode n, rlpEncode gp, rlpEncode gl, rlpEncode to', rlpEncode v, rlpEncode d ] rlpEncode ContractCreationTX{tNonce=n, gasPrice=gp, tGasLimit=gl, value=v, tInit=init'} = RLPArray [ rlpEncode n, rlpEncode gp, rlpEncode gl, rlpEncode (0::Integer), rlpEncode v, rlpEncode init' ] codeOrDataLength::Transaction->Int codeOrDataLength MessageTX{tData=d} = B.length d codeOrDataLength ContractCreationTX{tInit=d} = codeLength d zeroBytesLength::Transaction->Int zeroBytesLength MessageTX{tData=d} = length $ filter (==0) $ B.unpack d zeroBytesLength ContractCreationTX{tInit=Code d} = length $ filter (==0) $ B.unpack d