packages feed

burnt-explorer 1.0.0 → 2.0.0

raw patch · 3 files changed

+50/−24 lines, 3 filesdep +cassavadep ~aesondep ~bitcoin-script

Dependencies added: cassava

Dependency ranges changed: aeson, bitcoin-script

Files

Main.hs view
@@ -3,10 +3,10 @@  module Main (main) where -import Bitcoin.Script (Script)-import qualified Bitcoin.Script as BS+import qualified Data.Bitcoin.Script as BS import Data.Aeson-import Data.ByteString.Lazy.Char8 (pack)+import Data.ByteString.Lazy.Char8 (ByteString, pack, unpack)+import qualified Data.Csv as Csv import Data.List import Data.Scientific (Scientific, FPFormat(Fixed), formatScientific) import GHC.Generics@@ -14,18 +14,30 @@ import System.IO import System.Process +getBlackcoindCommand :: IO String+getBlackcoindCommand = do+  customName <- lookupEnv "BLACKCOIND_COMMAND"+  case customName of+    Just name -> return name+    Nothing -> return "blackcoind"+ execCommand :: String -> [String] -> IO String-execCommand command args = readProcess "blackcoind" ([command] ++ args) ""+execCommand command args = do+  blackcoindCommand <- getBlackcoindCommand+  let fullCommand = intercalate " " ([blackcoindCommand, command] ++ args)+  readCreateProcess (shell fullCommand) ""  data Block = Block {+  hash :: String,+  height :: Int,+  time :: Int,   tx :: [String]   } deriving (Generic, Show) instance FromJSON Block  data Tx = Tx {   txid :: String,-  vout :: [VOut],-  time :: Int+  vout :: [VOut]   } deriving (Generic, Show) instance FromJSON Tx @@ -33,7 +45,7 @@   n :: Int,   scriptHex :: String,   value :: Scientific,-  script :: Script+  script :: BS.Script   } deriving (Show) instance FromJSON VOut where   parseJSON (Object o) = do@@ -60,22 +72,31 @@   case decode (pack txJSON) of     Just tx -> return tx -show_tx_vout :: (Tx, VOut) -> String-show_tx_vout (tx, vout) =-  intercalate " " [txid tx,-                   show (n vout),-                   formatScientific Fixed Nothing (value vout),-                   scriptHex vout,-                   show (BS.scriptOps (script vout))]+ourEncodeOptions :: Csv.EncodeOptions+ourEncodeOptions = Csv.defaultEncodeOptions {+  Csv.encQuoting = Csv.QuoteMinimal+  } +blockTxVoutToCSV :: (Block, Tx, VOut) -> ByteString+blockTxVoutToCSV (block, tx, vout) =+  Csv.encodeWith ourEncodeOptions [(show (height block),+                                    hash block,+                                    show (time block),+                                    txid tx,+                                    show (n vout),+                                    formatScientific Fixed (Just 0) (100000000 * (value vout)),+                                    scriptHex vout,+                                    show (BS.scriptOps (script vout)))]+ processTxs :: [Int] -> IO () processTxs [] = return () processTxs (height:heights) = do   block <- getBlockByNumber height   txs <- getTxsFromBlock block-  let txs_vouts = concat [zip (repeat tx) (vout tx) | tx <- txs]-  let interesting = filter ((elem BS.OP_RETURN) . BS.scriptOps . script . snd) txs_vouts-  mapM_ (putStrLn . show_tx_vout) interesting+  let txs_vouts = concat [zip3 (repeat block) (repeat tx) (vout tx) | tx <- txs]+  let third (_, _, x) = x+  let interesting = filter ((elem BS.OP_RETURN) . BS.scriptOps . script . third) txs_vouts+  mapM_ (putStr . unpack . blockTxVoutToCSV) interesting   processTxs heights  main :: IO ()
README.md view
@@ -6,15 +6,19 @@ burnt-explorer <start height> <stop height> ``` -You must have the `blackcoind` binary (name currently hard-coded) available in `$PATH`.+It is assumed that you have `blackcoind` binary available in `$PATH`. If you want to use another command, set the `BLACKCOIND_COMMAND` environment variable. -Output format is the following:+Output format is [CSV (RFC 4180)](https://tools.ietf.org/html/rfc4180) without header, with minimal double quotes usage and with the following columns:  ```-<transaction id> <vout index> <value> <script hex> <decoded script>+<block height>,<block hash>,<block time>,<transaction id>,<vout index>,<satoshis burnt>,<script hex>,<decoded script> ``` -[`bitcoin-script` package](https://hackage.haskell.org/package/bitcoin-script) is used for decoding scripts.+[`bitcoin-script` package](https://hackage.haskell.org/package/bitcoin-script) is used for decoding scripts. If you don’t have a full-fledged CSV parser, you may want to omit the last field, for example by piping the output through `cut -d , -f -7`.++For prebuilt binaries, see job artifacts in [CI builds](https://gitlab.com/KrzysiekJ/burnt-explorer/pipelines).++This application uses [semantic versioning](http://semver.org/) 2.0.  ## License 
burnt-explorer.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                burnt-explorer-version:             1.0.0+version:             2.0.0 synopsis:            List OP_RETURN cryptocurrency transaction outputs. -- description: license:             Apache-2.0@@ -28,9 +28,10 @@   -- other-extensions:   build-depends:       base >=4.8 && <4.12                      , process >=1.6 && <1.7-                     , aeson >=1.2 && <1.3-                     , bitcoin-script >=0.9 && <0.10+                     , aeson >=1.4 && <1.5+                     , bitcoin-script >=0.11 && <0.12                      , bytestring >=0.10 && <0.11                      , scientific >=0.3 && <0.4+                     , cassava == 0.5.1.0   -- hs-source-dirs:   default-language:    Haskell2010