#!/bin/bash # ak-enter # # Using this tool, we can seek a whole zchain, 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 # $AK_ZLATEST environment variable. # # ak-enter [-n IPNS_LINK] # ak-enter [IPFS CID] # ak-enter -nV # ak-enter # # Returns a JSON array representing the chain retrieved. # Logs messages to $LOGSFILE. PROGRAM="$(basename $0)" logit(){ ak-logthis "<$PROGRAM>" "$1" "$2" } usage(){ echo "$PROGRAM - Crawl an arching kaos chain" echo "-----------------------------------" echo "Usage:" echo " --help, -h Print this help and exit" echo " --chain , -n Crawl specified chain" 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 based on AK_ZLATEST environment variable" } # Start of tests #entrance="QmW5WVXCJfhb4peHG6cbEdamC24vZzMX2Vz386vpENh38U" #entrance="QmNjQq7GkuXGF8kFT1z2Mv3i4JhY7sBXVUmHDiR1zkQjoE" #entrance="QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH" # End of tests verify=1 limit=0 fromIpns=0 VALID_ARGS=$(getopt -o hl:Nn:: --long help.ipns:,no-verify,chain:,limit:,beta,gamma:,delta: -- "$@") if [[ $? -ne 0 ]]; then exit 1; fi eval set -- "$VALID_ARGS" while [ : ]; do case "$1" in -h | --help) usage exit ;; -a | --alpha) echo "Processing 'alpha' option" shift ;; -l | --limit) limit=$2 shift 2 ;; -N | --no-verify) verify=0 shift ;; -n | --chain | --ipns) fromIpns=1 entrance="$(ak-ipns-resolve $2)" shift 2 ;; *) test="$2" if [ ! -z "$test" ] && [ "$fromIpns" == "0" ] then echo $test | grep -e 'Qm.\{44\}' >/dev/null if [ "$?" -ne 0 ] then logit "[ERROR]" "Argument provided was not an IPFS CIDv0 string" exit 1 fi entrance="$test" else entrance="$(cat $AK_ZLATEST)" fi break ;; :) echo -e "option requires an argument.\nUsage: $(basename $0) [-a] [-b] [-c arg]" exit 1 ;; ?) echo -e "Invalid command option.\nUsage: $(basename $0) [-a] [-b] [-c arg]" exit 1 ;; esac done #if [ ! -z "$1" ] && [ "$1" == "-h" ] || [ "$1" == "--help" ] #then # usage # exit #elif [ ! -z "$1" ] && [ "$1" == "-nV" ] || [ "$1" == "--no-verify" ] #then # verify=0 # entrance="$(cat $AK_ZLATEST)" #elif [ ! -z "$1" ] && [ "$1" == "-n" ] #then # entrance="$(ak-ipns-resolve $2)" #elif [ ! -z "$1" ] && [ "$1" == "-l" ] #then # limit=$2 # if [ ! -z "$3" ] # then # echo $3 | grep -e 'Qm.\{44\}' >/dev/null # if [ "$?" -ne 0 ] # then # logit "[ERROR]" "Argument provided was not an IPFS CIDv0 string" # exit 1 # fi # entrance="$3" # else # entrance="$(cat $AK_ZLATEST)" # fi #elif [ ! -z "$1" ] #then # echo $1 | grep -e 'Qm.\{44\}' >/dev/null # if [ "$?" -ne 0 ] # then # logit "[ERROR]" "Argument provided was not an IPFS CIDv0 string" # exit 1 # fi # entrance="$1" #else # By default we ak-enter from the latest block # We can alter this by changing this value # entrance="$(cat $AK_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 $AK_ZGENESIS)" # We assume that we found the entrance inside a block, hence # ZBLOCK is labeled as previous zblock="$entrance" # Enter temp folder TEMPASSIN="$(ak-tempassin)" cd $TEMPASSIN counter=0 # The loop # We break the loop from inside the loop while true && [ $limit="0" ] do if [ $counter == 0 ] then echo -n '[' 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 logs which ZBLOCK is being read at the moment logit "[INFO]" "Examining $zblock" echo -n '{"zblock":"'$zblock'",' # We concatenate the zblock's contents, pipe # them through filter ak-json2bash and output # them to tmp-file # # We check if any $zblock at all ak-ipfs-cat $zblock > /dev/null 2>&1 if [ "$?" -ne 0 ] then logit "[ERROR]" "ZBLOCK $zblock READ failed" exit 1 fi logit "[INFO]" "ZBLOCK $zblock READ" # If it's JSON formated ak-ipfs-cat $zblock | jq -M > /dev/null 2>&1 if [ "$?" -ne 0 ] then logit "[ERROR]" "ZBLOCK $zblock is not JSON" exit 1 fi logit "[INFO]" "ZBLOCK $zblock is JSON" # Then we pass it through the filter and save it ak-ipfs-cat $zblock | jq -M | ak-json2bash > tmp-zblock # 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' tmp-zblock > /dev/null 2>&1 if [ "$?" -ne 0 ] then logit "[ERROR]" "ZBLOCK $zblock doesn't contain a block_signature" exit 1 fi logit "[INFO]" "ZBLOCK $zblock contains a block_signature" grep -e 'block=' tmp-zblock > /dev/null 2>&1 if [ "$?" -ne 0 ] then logit "[ERROR]" "ZBLOCK $zblock has no block" exit 1 fi logit "[INFO]" "ZBLOCK $zblock has block" # We create files named after each ZBLOCK IPFS CID for later # reference. Files are empty. touch $AK_ZBLOCKDIR/$zblock logit "[INFO]" "Created reference" # 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 tmp-zblock logit "[INFO]" "ZBLOCK SOURCED" # Same as above applies to BLOCK and DATA subparts of each ZBLOCK # BLOCKS echo -n '"block":"'$block'",' ak-ipfs-cat $block | jq -M | ak-json2bash > tmp-block if [ "$?" -ne 0 ] then logit "[ERROR]" "BLOCK $block READ failed" exit 1 fi grep -e 'timestamp' -e 'gpg' -e 'data' -e 'action' -e 'detach' -e 'previous' tmp-block > /dev/null 2>&1 if [ "$?" -ne 0 ] then logit "[ERROR]" "BLOCK $block is NOT a valid block" exit 1 fi logit "[INFO]" "BLOCK $block is a block" source tmp-block logit "[INFO]" "BLOCK $block SOURCED" touch $AK_BLOCKDIR/$block logit "[INFO]" "BLOCK REFERENCED" module="$(echo $action | sed -e 's/\// /g' | awk '{ print $1 }')" logit "[INFO]" "DATA is $module module." command="$(echo $action | sed -e 's/\// /g' | awk '{ print $2 }')" logit "[INFO]" "COMMAND is $command" if [ ! -v $timestamp ] then echo -n '"timestamp":"'$timestamp'",' fi echo -n '"block_signature":"'$block_signature'",' echo -n '"detach":"'$detach'",' echo -n '"module":"'$module'",' echo -n '"action":"'$command'",' echo -n '"gpg":"'$gpg'",' if [ $verify == 1 ] then ak-ipfs-get $gpg > /dev/null 2>&1 if [ "$?" -ne 0 ] then logit "[ERROR]" "Could not get GPG key: $gpg ." exit 1 fi gpg2 --import $gpg > /dev/null 2>&1 if [ "$?" -ne 0 ] then logit "[ERROR]" "Could not import GPG key: $gpg ." exit 1 fi ak-ipfs-get $block_signature > /dev/null 2>&1 if [ "$?" -ne 0 ] then logit "[ERROR]" "Error while getting $block_signature for $block" exit 1 fi mv $block_signature $block.asc logit "[INFO]" "Block signature downloaded" ak-ipfs-get $block > /dev/null 2>&1 if [ "$?" -ne 0 ] then logit "[ERROR]" "Could not get $block block" exit 1 fi logit "[INFO]" "Downloaded block $block." gpg2 --verify $block.asc > /dev/null 2>&1 if [ "$?" -ne 0 ] then logit "[ERROR]" "Could not verify $block with GPG key $gpg." exit 1 fi logit "[GPG]" "$gpg signature of $block is verified." fi ak-data-expand $data $gpg if [ "$?" -ne 0 ] then logit "[ERROR]" "Failed on data signature verification [data: $data, gpg: $gpg, zblock: $zblock]" exit 1 fi # DATA (but we don't source it's stuff) # Only print to stdout #ak-ipfs-cat $data touch $AK_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 logit "[WARNING]" "Block $block has no previous zblock, appending pseudo genesis to exit gracefully." echo -n '"previous":"genesis"},{"genesis":"genesis"}]' logit "[INFO]" "Reached pseudo-genesis, counted $counter zblocks." exit 0 # Otherwise, we inform of the sequence else #echo "$zblock after $previous" logit "[INFO]" "Found a previous block for $zblock: $previous" echo -n '"previous":"'$previous'"}' zblock=$previous fi if [ "$limit" != "0" ] && [ "$limit" == "$counter" ] then echo -n ']' exit 0 else echo -n ',' fi # Now check if it is equal to the seed # which apparently means we reached the seed. elif [ "$zblock" == "$seed" ] then echo -n '{"genesis":"genesis"}]' logit "[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