Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
scarb 2.9.2
starkli 0.4.2
25 changes: 8 additions & 17 deletions scripts/get_tx_from_block.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,22 @@ fi
BLOCK_HEIGHT=$1
TX_INDEX=$2

RPC_API="https://bitcoin-mainnet.public.blastapi.io"
BLOCKSTREAM_API="https://blockstream.info/api"

# First, get the block hash for the given height
BLOCK_HASH_RES=$(curl -s -X POST -H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"1.0\",\"id\":0,\"method\":\"getblockhash\",\"params\":[$BLOCK_HEIGHT]}" \
$RPC_API)
# Get the block hash for the given height
BLOCK_HASH=$(curl -s "$BLOCKSTREAM_API/block-height/$BLOCK_HEIGHT")

BLOCK_HASH=$(echo $BLOCK_HASH_RES | jq -r '.result')

if [ -z "$BLOCK_HASH" ] || [ "$BLOCK_HASH" = "null" ]; then
if [ -z "$BLOCK_HASH" ] || [ "$BLOCK_HASH" = "Block not found" ]; then
echo "Error: Could not fetch block hash for height $BLOCK_HEIGHT"
exit 1
fi

# Then, get the block data which includes all transaction hashes
BLOCK_DATA_RES=$(curl -s -X POST -H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"1.0\",\"id\":0,\"method\":\"getblock\",\"params\":[\"$BLOCK_HASH\"]}" \
$RPC_API)

# Extract the transaction hash at the specified index
TX_HASH=$(echo $BLOCK_DATA_RES | jq -r ".result.tx[$TX_INDEX]")
# Get the transaction hash at the specified index
TX_HASH=$(curl -s "$BLOCKSTREAM_API/block/$BLOCK_HASH/txid/$TX_INDEX")

if [ -z "$TX_HASH" ] || [ "$TX_HASH" = "null" ]; then
if [ -z "$TX_HASH" ] || [ "$TX_HASH" = "Transaction not found" ]; then
echo "Error: Could not find transaction at index $TX_INDEX in block $BLOCK_HEIGHT"
exit 1
fi

echo $TX_HASH
echo $TX_HASH
104 changes: 57 additions & 47 deletions scripts/run_bitcoin_transaction.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ BIP_341_BLOCK_HEIGHT=709632 # Taproot

TXID=$1

RPC_API="https://bitcoin-mainnet.public.blastapi.io"
BLOCKSTREAM_API="https://blockstream.info/api"

# Input needed
# raw_transaction_hex: ByteArray,
Expand All @@ -24,37 +24,46 @@ RPC_API="https://bitcoin-mainnet.public.blastapi.io"
# pub amount: i64,
# pub pubkey_script: ByteArray,
# pub block_height: i32,
# pub flags: ByteArray,
#}

# Fetch the transaction
RES=$(curl -s -X POST -H "Content-Type: application/json" -d "{\"jsonrpc\":\"1.0\",\"id\":0,\"method\":\"getrawtransaction\",\"params\":[\"$TXID\", true]}" $RPC_API)
TX_JSON=$(curl -s "$BLOCKSTREAM_API/tx/$TXID")

RAW_TX_HEX=$(echo $RES | jq '.result.hex' | tr -d '"')
# Validate response
if [ -z "$TX_JSON" ] || ! echo "$TX_JSON" | jq -e '.txid' > /dev/null 2>&1; then
echo "Error: Could not fetch transaction $TXID"
exit 1
fi

# Fetch raw transaction hex
RAW_TX_HEX=$(curl -s "$BLOCKSTREAM_API/tx/$TXID/hex")
RAW_TX_HEX="0x$RAW_TX_HEX"
# echo "RAW_TX_HEX: $RAW_TX_HEX"

RAW_TX_TEXT=$($SCRIPT_DIR/text_to_byte_array.sh $RAW_TX_HEX)
RAW_TX_INPUT=$(sed 's/^\[\(.*\)\]$/\1/' <<< $RAW_TX_TEXT)
# echo "RAW_TX_INPUT: $RAW_TX_INPUT"

# Fetch the vin's for utxo_hints
VINS=$(echo $RES | jq '.result.vin')
# echo "VINS: $VINS"

# Get block hash from transaction
BLOCK_HASH=$(echo $RES | jq -r '.result.blockhash')
# Fetch block info to get height
BLOCK_INFO=$(curl -s -X POST -H "Content-Type: application/json" -d "{\"jsonrpc\":\"1.0\",\"id\":0,\"method\":\"getblock\",\"params\":[\"$BLOCK_HASH\"]}" $RPC_API)
BLOCK_HEIGHT=$(echo $BLOCK_INFO | jq -r '.result.height')
# Get block height from transaction status
BLOCK_HEIGHT=$(echo $TX_JSON | jq -r '.status.block_height')
echo "BLOCK_HEIGHT: $BLOCK_HEIGHT"
BLOCK_VERSION=$(echo $BLOCK_INFO | jq -r '.result.version')

# Get block version (fetch block info)
BLOCK_HASH=$(echo $TX_JSON | jq -r '.status.block_hash')
BLOCK_JSON=$(curl -s "$BLOCKSTREAM_API/block/$BLOCK_HASH")

# Validate block response
if [ -z "$BLOCK_JSON" ] || ! echo "$BLOCK_JSON" | jq -e '.id' > /dev/null 2>&1; then
echo "Error: Could not fetch block $BLOCK_HASH"
exit 1
fi

BLOCK_VERSION=$(echo $BLOCK_JSON | jq -r '.version')

# Check if this is a coinbase transaction
IS_COINBASE=false
VIN_TXID=$(echo $RES | jq -r '.result.vin[0].txid')
if [ "$VIN_TXID" = "null" ] || [ "$VIN_TXID" = "0000000000000000000000000000000000000000000000000000000000000000" ]; then
IS_COINBASE=true
IS_COINBASE=$(echo $TX_JSON | jq -r '.vin[0].is_coinbase')

if [ "$IS_COINBASE" = "true" ]; then
echo "Detected coinbase transaction"
FLAGS="" # Empty flags for coinbase
else
Expand Down Expand Up @@ -98,47 +107,48 @@ else
fi
fi

echo "Transaction type: $([ "$IS_COINBASE" = true ] && echo 'Coinbase' || echo 'Regular')"
echo "Transaction type: $([ "$IS_COINBASE" = "true" ] && echo 'Coinbase' || echo 'Regular')"
echo "Block height: $BLOCK_HEIGHT"
echo "Script flags: $FLAGS"
echo "UTXO construction: $UTXOS"

AMOUNT=0 # TODO?
if [ "$IS_COINBASE" = true ]; then
if [ "$IS_COINBASE" = "true" ]; then
echo "Setting up empty UTXO list for coinbase transaction"
# Leave UTXOS empty for coinbase transactions
UTXOS=""
else
UTXOS=""
for vin in $(echo $VINS | jq -r '.[] | @base64'); do
_jq() {
echo ${vin} | base64 --decode | jq -r ${1}
}

TXID=$(echo $(_jq '.txid'))
VOUT=$(echo $(_jq '.vout'))

# Fetch the transaction
RES=$(curl -s -X POST -H "Content-Type: application/json" -d "{\"jsonrpc\":\"1.0\",\"id\":0,\"method\":\"getrawtransaction\",\"params\":[\"$TXID\", true]}" $RPC_API)

AMOUNT=$(echo $RES | jq ".result.vout[$VOUT].value * 100000000 | floor")
PUBKEY_SCRIPT=$(echo $RES | jq ".result.vout[$VOUT].scriptPubKey.hex" | tr -d '"')
PUBKEY_SCRIPT="0x$PUBKEY_SCRIPT"

PUBKEY_SCRIPT_TEXT=$($SCRIPT_DIR/text_to_byte_array.sh $PUBKEY_SCRIPT)
PUBKEY_SCRIPT_INPUT=$(sed 's/^\[\(.*\)\]$/\1/' <<< $PUBKEY_SCRIPT_TEXT)

UTXOS="$UTXOS$AMOUNT,$PUBKEY_SCRIPT_INPUT,$BLOCK_HEIGHT"
done
UTXOS=$(sed 's/,$//' <<< $UTXOS)
# Blockstream API includes prevout info directly in vin
VINS=$(echo $TX_JSON | jq -c '.vin[]')

while IFS= read -r vin; do
AMOUNT=$(echo $vin | jq -r '.prevout.value')
PUBKEY_SCRIPT=$(echo $vin | jq -r '.prevout.scriptpubkey')
PUBKEY_SCRIPT="0x$PUBKEY_SCRIPT"

PUBKEY_SCRIPT_TEXT=$($SCRIPT_DIR/text_to_byte_array.sh $PUBKEY_SCRIPT)
PUBKEY_SCRIPT_INPUT=$(sed 's/^\[\(.*\)\]$/\1/' <<< $PUBKEY_SCRIPT_TEXT)

if [ -n "$UTXOS" ]; then
UTXOS="$UTXOS,"
fi
# UTXO fields are flattened: amount, pubkey_script (data, pending_word, pending_word_len), block_height
UTXOS="$UTXOS$AMOUNT,$PUBKEY_SCRIPT_INPUT,$BLOCK_HEIGHT"
done <<< "$VINS"
fi

FLAGS_TEXT=$($SCRIPT_DIR/text_to_byte_array.sh "$FLAGS")
FLAGS_INPUT=$(sed 's/^\[\(.*\)\]$/\1/' <<< $FLAGS_TEXT)

JOINED_INPUT="[$RAW_TX_INPUT,[$UTXOS],$FLAGS_INPUT]"
# Convert txid to u256 (low, high)
# txid is 32 bytes (64 hex chars), need to split into two u128 values
# Note: Bitcoin txids are displayed in reverse byte order
TXID_REVERSED=$(echo $TXID | fold -w2 | tac | tr -d '\n')
TXID_UPPER=$(echo $TXID_REVERSED | tr '[:lower:]' '[:upper:]')
TXID_HIGH=$(echo "ibase=16; ${TXID_UPPER:0:32}" | bc | tr -d '\\\n')
TXID_LOW=$(echo "ibase=16; ${TXID_UPPER:32:32}" | bc | tr -d '\\\n')

JOINED_INPUT="[$RAW_TX_INPUT,[$UTXOS],$FLAGS_INPUT,$TXID_LOW,$TXID_HIGH]"
# echo "JOINED_INPUT: $JOINED_INPUT"

echo "scarb cairo-run --package shinigami_cmds --function run_raw_transaction \"$JOINED_INPUT\""
scarb cairo-run --package shinigami_cmds --function run_raw_transaction --no-build $JOINED_INPUT
# TODO: Error checking
scarb cairo-run --package shinigami_cmds --function run_raw_transaction $JOINED_INPUT
# TODO: Error checking
23 changes: 15 additions & 8 deletions scripts/run_block_transactions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,21 @@ echo "Running block $BLOCK"
OUTPUTS=$BASE_DIR/outputs/block-$BLOCK
mkdir -p $OUTPUTS

RPC_API="https://bitcoin-mainnet.public.blastapi.io"
BLOCKSTREAM_API="https://blockstream.info/api"

# Fetch blockhash
RES=$(curl -s -X POST -H "Content-Type: application/json" -d "{\"jsonrpc\":\"1.0\",\"id\":0,\"method\":\"getblockhash\", \"params\": [$BLOCK]}" $RPC_API)
BLOCKHASH=$(echo $RES | jq -r '.result')
# Fetch block hash
BLOCKHASH=$(curl -s "$BLOCKSTREAM_API/block-height/$BLOCK")

# Fetch the block
RES=$(curl -s -X POST -H "Content-Type: application/json" -d "{\"jsonrpc\":\"1.0\",\"id\":0,\"method\":\"getblock\", \"params\": [\"$BLOCKHASH\"]}" $RPC_API)
if [ -z "$BLOCKHASH" ] || [ "$BLOCKHASH" = "Block not found" ]; then
echo "Error: Could not fetch block hash for height $BLOCK"
exit 1
fi

# Fetch the block transaction list
TXIDS=$(curl -s "$BLOCKSTREAM_API/block/$BLOCKHASH/txids")

# Get total transaction count
TX_COUNT=$(echo $TXIDS | jq -r 'length')

# Loop through the transactions
FIRST_IDX=$2
Expand All @@ -27,11 +34,11 @@ if [ -z "$FIRST_IDX" ]; then
fi
LAST_IDX=$3
if [ -z "$LAST_IDX" ]; then
LAST_IDX=$(echo $RES | jq -r ".result.tx | length")
LAST_IDX=$TX_COUNT
fi
IDX=$FIRST_IDX
while true; do
TXID=$(echo $RES | jq -r ".result.tx[$IDX]")
TXID=$(echo $TXIDS | jq -r ".[$IDX]")
if [ "$TXID" == "null" ]; then
break
fi
Expand Down
2 changes: 1 addition & 1 deletion scripts/run_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ SCRIPTSIG=$($SCRIPT_DIR/text_to_byte_array.sh "$SCRIPTIN")
# Remove outer brackets []
SCRIPTSIG=${SCRIPTSIG:1:${#SCRIPTSIG}-2}

JOINED_INPUTS="[[],0,0,$SCRIPTSIG]"
JOINED_INPUTS="[[],0,0,$SCRIPTSIG,0,0]"

echo "scarb cairo-run --package shinigami_cmds --function run $JOINED_INPUTS"
scarb cairo-run --package shinigami_cmds --function run $JOINED_INPUTS
Expand Down