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 +38/−17
- README.md +8/−4
- burnt-explorer.cabal +4/−3
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