#!/bin/bash # enter # # Using this tool, we can seek a whole chain if available from an # IPFS CID or an IPNS link. Default (no arguments) will retrieve # the local ZCHAIN starting from the IPFS CID stored in the file # that is tracked by the $ZLATEST environment variable. # # enter [-n IPNS_LINK] # enter [IPFS CID] # enter # # Returns a JSON array representing the chain retrieved and logs # messages to LOGSFILE usage(){ echo "enter - Crawl an arching kaos chain" echo "-----------------------------------" echo "Usage:" echo " --help, -h Print this help and exit" echo " --chain , -n Crawl specified chain" echo " --show-zblocks-only, -z Show only zblocks" echo " --no-verify, -nV Don't verify signatures" echo " Specify IPFS CID for entrance" echo "" echo "Note that combined flags don't work for now" echo "Running with no flags crawls your chain" } # Start of tests #entrance="QmW5WVXCJfhb4peHG6cbEdamC24vZzMX2Vz386vpENh38U" #entrance="QmNjQq7GkuXGF8kFT1z2Mv3i4JhY7sBXVUmHDiR1zkQjoE" #entrance="QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH" # End of tests verify=1 if [ ! -z "$1" ] && [ "$1" == "-h" ] || [ "$1" == "--help" ] then usage exit elif [ ! -z "$1" ] && [ "$1" == "-nV" ] || [ "$1" == "--no-verify" ] then verify=0 entrance="$(cat $ZLATEST)" elif [ ! -z "$1" ] && [ "$1" == "-n" ] then entrance="$(ipns-resolve $2)" elif [ ! -z "$1" ] && [ "$1" == "--show-zblocks-only" ] || [ "$1" == "-z" ] then # Enter temp folder TEMPASSIN="/tmp/aktmp_$(date -u +%s)" mkdir $TEMPASSIN cd $TEMPASSIN ccounter=0 entrance="$(cat $ZLATEST)" seed="$(cat $ZGENESIS)" echo '[' zblock=$entrance while true do if [ "$counter" == 0 ] then echo "[" fi counter=$(expr $counter + 1) if [ ! -v $zblock ] then if [ "$zblock" != "$seed" ] then timestamp='' echo '{"zblock":"'$zblock'",' ipfs cat $zblock | json2bash > $TEMPASSIN/tmp-zblock source $TEMPASSIN/tmp-zblock ipfs cat $block | json2bash > $TEMPASSIN/tmp-block source $TEMPASSIN/tmp-block logthis "[INFO]" "BLOCK REFERENCED" if [ ! -v $timestamp ] then echo '"timestamp":"'$timestamp'",' fi echo '"block_signature":"'$block_signature'",' echo '"gpg":"'$gpg'",' if [ -v $previous ] then logthis "[ERROR]" "Block $block has no previous zblock $previous. Appending default genesis to close cleanly." echo '"previous":"genesis"},{"genesis":"genesis"}]' exit 0 else echo '"previous":"'$previous'"},' zblock=$previous fi elif [ "$zblock" == "$seed" ] then echo '{"genesis":"genesis"}]' logthis "[INFO]" "Counter $counter" exit 0 fi else echo "Check not passed... No previous IPFS CID" exit 1 fi done elif [ ! -z "$1" ] then entrance="$1" else # By default we enter from the latest block # We can alter this by changing this value entrance="$(cat $ZLATEST)" fi # We assign the IPFS CIDv0 of an empty file as this is used # as our GENESIS block, hence the "seed" that the tree grows # from. seed="$(cat $ZGENESIS)" # We assume that we found the entrance inside a block, hence # ZBLOCK is labeled as previous zblock="$entrance" # Enter temp folder TEMPASSIN="/tmp/aktmp_$(date -u +%s)" mkdir $TEMPASSIN cd $TEMPASSIN counter=0 # The loop # We break the loop from inside the loop while true do if [ $counter == 0 ] then echo '[' fi counter=$(expr $counter + 1) # Check if $zblock exists as variable if [ ! -v $zblock ] then # Check if it is not our seed cause if it is we skip this part if [ "$zblock" != "$seed" ] then # Reset timestamp since it's introduced later timestamp='' # Announce to stdout which ZBLOCK is being read at the moment logthis "[INFO]" "Examining $zblock" echo '{"zblock":"'$zblock'",' # We create files named after each ZBLOCK IPFS CID for later # reference. Files are empty. touch $ZBLOCKDIR/$zblock logthis "[INFO]" "Created reference" # We concatenate the zblock's contents, pipe them through filter # json2bash and output them to tmp-file ipfs cat $zblock | json2bash > $TEMPASSIN/tmp-zblock if [ "$?" == 0 ] then logthis "[INFO]" "ZBLOCK $zblock READ" else logthis "[ERROR]" "ZBLOCK $zblock READ failed" exit 1 fi # Be sure that there are the expected values # We need 'block' and 'block_signature' inside a 'zblock' # Exit if any is missing grep -e 'block_signature' $TEMPASSIN/tmp-zblock > /dev/null 2>&1 if [ "$?" == 0 ] then logthis "[INFO]" "ZBLOCK $zblock has block_signature" else logthis "[ERROR]" "ZBLOCK $zblock has no block_signature" exit 1 fi grep -e 'block=' $TEMPASSIN/tmp-zblock > /dev/null 2>&1 if [ "$?" == 0 ] then logthis "[INFO]" "ZBLOCK $zblock has block" else logthis "[ERROR]" "ZBLOCK $zblock has no block" exit 1 fi # Supposingly you are on a safe environment and you only have # access to your chain, I would consider mild secure to source # the files into your bash. # File an issue/pull request if you think it can be done better!! source $TEMPASSIN/tmp-zblock logthis "[INFO]" "ZBLOCK SOURCED" # Same as above applies to BLOCK and DATA subparts of each ZBLOCK # BLOCKS echo '"block":"'$block'",' ipfs cat $block | json2bash > $TEMPASSIN/tmp-block if [ "$?" == 0 ] then logthis "[INFO]" "BLOCK $block READ" else logthis "[ERROR]" "BLOCK $block READ failed" exit 1 fi grep -e 'timestamp' -e 'gpg' -e 'data' -e 'action' -e 'detach' -e 'previous' $TEMPASSIN/tmp-block > /dev/null 2>&1 if [ "$?" == 0 ] then logthis "[INFO]" "BLOCK $block is a block" else logthis "[ERROR]" "BLOCK $block is NOT a valid block" exit 1 fi source $TEMPASSIN/tmp-block logthis "[INFO]" "BLOCK $block SOURCED" touch $BLOCKDIR/$block logthis "[INFO]" "BLOCK REFERENCED" module="$(echo $action | sed -e 's/\// /g' | awk '{ print $1 }')" logthis "[INFO]" "DATA is $module module." command="$(echo $action | sed -e 's/\// /g' | awk '{ print $2 }')" logthis "[INFO]" "COMMAND is $command" if [ ! -v $timestamp ] then echo '"timestamp":"'$timestamp'",' fi echo '"block_signature":"'$block_signature'",' echo '"detach":"'$detach'",' echo '"module":"'$module'",' echo '"action":"'$command'",' echo '"gpg":"'$gpg'",' if [ $verify == 1 ] then ipfs get $gpg > /dev/null 2>&1 if [ "$?" == 0 ] then gpg2 --import $gpg > /dev/null 2>&1 if [ "$?" == 0 ] then logthis "[INFO]" "$gpg imported." else logthis "[ERROR]" "Could not import GPG key: $gpg ." exit 1 fi else logthis "[ERROR]" "Could not get GPG key: $gpg ." exit 1 fi ipfs get $block_signature > /dev/null 2>&1 if [ "$?" == 0 ] then mv $block_signature $block.asc logthis "[GPG]" "Block signature downloaded" else logthis "[ERROR]" "Error while getting $block_signature for $block" exit 1 fi ipfs get $block > /dev/null 2>&1 if [ "$?" == 0 ] then logthis "[INFO]" "Downloaded block $block." else logthis "[ERROR]" "Could not get $block block" exit 1 fi gpg2 --verify $block.asc > /dev/null 2>&1 if [ "$?" == 0 ] then logthis "[GPG]" "$gpg signature of $block is verified." else logthis "[ERROR]" "Could not verify $block with GPG key $gpg." exit 1 fi fi profile show $data # DATA (but we don't source it's stuff) # Only print to stdout #ipfs cat $data touch $DATADIR/$data # Now, since we sourced the BLOCK to our terminal, we can search # for $previous variable. In case we don't find one, we append one # and we exit. if [ -v $previous ] then logthis "[WARNING]" "Block $block has no previous zblock, appending pseudo genesis to exit gracefully." echo '"previous":"genesis"},{"genesis":"genesis"}]' exit 0 # Otherwise, we inform of the sequence else #echo "$zblock after $previous" logthis "[INFO]" "Found a previous block: $previous" echo '"previous":"'$previous'"},' zblock=$previous fi # Now check if it is equal to the seed # which apparently means we reached the seed. elif [ "$zblock" == "$seed" ] then #echo "$zblock is GENESIS block" #echo '"'$zblock'":{ "GENESIS":"GENESIS"}] ' echo '{"genesis":"genesis"}]' logthis "[INFO]" "Reached $seed, counted $counter zblocks." exit 0 fi # And finally, if nothing is there exit with error else echo "Check not passed... No previous IPFS CID" exit 1 fi done