Skip to content

update exercises

update exercises #19

Workflow file for this run

name: Run Setup Script
on:
push:
branches:
- main # Trigger on pushes to the main branch
jobs:
bitcoin-setup:
runs-on: ubuntu-latest # Use the latest Ubuntu environment
steps:
- name: Checkout repository
uses: actions/checkout@v4 # Check out the repository code
- name: Cache Bitcoin Core
id: cache-bitcoin
uses: actions/cache@v3
with:
path: |
bitcoin-28.0
bitcoin-28.0-x86_64-linux-gnu.tar.gz
key: bitcoin-core-28.0
- name: Setup Bitcoin Core
run: |
if [ "${{ steps.cache-bitcoin.outputs.cache-hit }}" != 'true' ]; then
wget https://bitcoincore.org/bin/bitcoin-core-28.0/bitcoin-28.0-x86_64-linux-gnu.tar.gz
tar -xzvf bitcoin-28.0-x86_64-linux-gnu.tar.gz
fi
sudo bash .github/setup.sh
- name: Start bitcoind in regtest mode
run: |
bitcoind -regtest -daemon
echo "Waiting for bitcoind to be ready..."
# Wait for bitcoind to start (max 30s)
for i in {1..30}; do
if bitcoin-cli -regtest getblockchaininfo > /dev/null 2>&1; then
echo "✅ bitcoind is ready!"
break
fi
echo "Still waiting for bitcoind..."
sleep 1
done
- name: 01.sh - Verify Wallet Creation
run: |
chmod +x submission/01.sh
WALLET=$(submission/01.sh)
if [[ "$WALLET" == *"btrustwallet"* ]]; then
echo "✅ Success: Wallet creation passed!"
else
echo "❌ Error: Wallet creation failed!"
exit 1
fi
- name: 02.sh - Verify Change Address Generation
run: |
chmod +x submission/02.sh
CHANGE_ADDRESS=$(submission/02.sh)
if [[ "$CHANGE_ADDRESS" =~ ^bcrt1[ac-hj-np-z02-9]{8,87}$ ]]; then
echo "✅ Success: Change address generation passed!"
else
echo "❌ Error: Change address generation failed!"
exit 1
fi
- name: 03.sh - Verify Adding Funds to SegWit Address
run: |
chmod +x submission/03.sh
ADD=$(submission/03.sh)
BALANCE=$(bitcoin-cli -regtest getreceivedbyaddress "$ADD" 0)
if (( $(echo "$BALANCE > 0" | bc -l) )); then
echo "✅ Success: Adding funds to SegWit address passed!"
else
echo "❌ Error: Adding funds to SegWit address failed!"
exit 1
fi
- name: 04.sh - Verify Listing the current UTXOs in your wallet.
run: |
chmod +x submission/04.sh
UTXOs=$(submission/04.sh)
if [[ "$UTXOs" != "[]" && "$UTXOs" =~ "txid" ]]; then
echo "✅ Success: Listing the current UTXOs in your wallet passed!"
else
echo "❌ Error: Listing the current UTXOs in your wallet failed!"
exit 1
fi
- name: 05.sh - Verify Transaction ID
run: |
chmod +x submission/05.sh
TRANSACTION_ID=$(submission/05.sh)
EXPECTED_OUTPUT=23c19f37d4e92e9a115aab86e4edc1b92a51add4e0ed0034bb166314dde50e16
if [[ "$TRANSACTION_ID" == "$EXPECTED_OUTPUT" ]]; then
echo "✅ Success: Transaction ID Check passed!"
else
echo "❌ Error: Transaction ID Check failed!"
exit 1
fi
- name: 06.sh - Verify Total Transaction Output Amount In Satoshis
run: |
chmod +x submission/06.sh
ACTUAL_OUTPUT=$(submission/06.sh)
EXPECTED_OUTPUT=23679108
if [[ "$ACTUAL_OUTPUT" == "$EXPECTED_OUTPUT" ]]; then
echo "✅ Success: Total Transaction Output Amount In Satoshis Check passed!"
else
echo "❌ Error: Total Transaction Output Amount In Satoshis Check failed!"
exit 1
fi
- name: 07.sh - Verify Raw Transaction Hex
run: |
chmod +x submission/07.sh
ACTUAL_OUTPUT=$(submission/07.sh)
EXPECTED_OUTPUT=0200000002160ee5dd146316bb3400ede0d4ad512ab9c1ede486ab5a119a2ee9d4379fc1230000000000fdffffff160ee5dd146316bb3400ede0d4ad512ab9c1ede486ab5a119a2ee9d4379fc1230100000000fdffffff01002d31010000000017a91421ed90762e16eaaea188aae19142e5b25bf75d238700000000
if [[ "$ACTUAL_OUTPUT" == "$EXPECTED_OUTPUT" ]]; then
echo "✅ Success: Raw Transaction Hex Check passed!"
else
echo "❌ Error: Raw Transaction Hex Check failed!"
exit 1
fi
- name: 08.sh - Verify Raw Transaction Hex
run: |
chmod +x submission/08.sh
ACTUAL_OUTPUT=$(submission/08.sh)
EXPECTED_OUTPUT=0200000002160ee5dd146316bb3400ede0d4ad512ab9c1ede486ab5a119a2ee9d4379fc1230000000000fdffffff160ee5dd146316bb3400ede0d4ad512ab9c1ede486ab5a119a2ee9d4379fc1230100000000fdffffff01640269010000000017a91421ed90762e16eaaea188aae19142e5b25bf75d238700000000
if [[ "$ACTUAL_OUTPUT" == "$EXPECTED_OUTPUT" ]]; then
echo "✅ Success: Raw Transaction Hex Check passed!"
else
echo "❌ Error: Raw Transaction Hex Check failed!"
exit 1
fi
- name: 09.sh - Verify Raw Transaction Hex
run: |
chmod +x submission/09.sh
ACTUAL_OUTPUT=$(submission/09.sh)
EXPECTED_OUTPUT=0200000002160ee5dd146316bb3400ede0d4ad512ab9c1ede486ab5a119a2ee9d4379fc123000000000001000000160ee5dd146316bb3400ede0d4ad512ab9c1ede486ab5a119a2ee9d4379fc12301000000000100000001002d31010000000017a91421ed90762e16eaaea188aae19142e5b25bf75d238700000000
if [[ "$ACTUAL_OUTPUT" == "$EXPECTED_OUTPUT" ]]; then
echo "✅ Success: Raw Transaction Hex Check passed!"
else
echo "❌ Error: Raw Transaction Hex Check failed!"
exit 1
fi
- name: final.sh - Verify Advanced Transaction Exercise
run: |
chmod +x submission/final.sh
echo "Running finalexercise script..."
# Run the script with a timeout to handle potential infinite loops
ACTUAL_OUTPUT=$(timeout 30s submission/final.sh || echo "ERROR: Script execution failed or timed out")
ACTUAL_OUTPUT=${ACTUAL_OUTPUT: -164}
# First check: Verify output is a valid transaction hex string
if ! [[ $ACTUAL_OUTPUT =~ ^02[0-9a-fA-F]+$ ]]; then
echo "❌ Error: Advanced Transaction Exercise failed! Output is not a valid hex string."
echo "Output: $ACTUAL_OUTPUT"
exit 1
fi
echo "✓✅ Basic check passed: Output is a valid hex string format"
# Second check: Verify it's a valid Bitcoin transaction
echo "Verifying transaction validity..."
DECODED_TX=$(bitcoin-cli -regtest decoderawtransaction "$ACTUAL_OUTPUT" 2>/dev/null)
if [ $? -ne 0 ]; then
echo "❌ Error: Invalid transaction format! The hex string is not a valid Bitcoin transaction."
exit 1
fi
echo "✓✅ Transaction validity check passed: Output is a valid Bitcoin transaction"
# Third check: Verify RBF is enabled via sequence numbers
echo "Checking RBF implementation..."
VIN_SEQUENCES=$(echo "$DECODED_TX" | jq -r '.vin[].sequence')
RBF_ENABLED=false
for seq in $VIN_SEQUENCES; do
# Any sequence number below 0xFFFFFFFE (4294967294) enables RBF
if [ "$seq" -lt 4294967294 ]; then
RBF_ENABLED=true
break
fi
done
if [ "$RBF_ENABLED" = false ]; then
echo "❌ Error: RBF not enabled! All sequence numbers are ≥ 4294967294."
exit 1
fi
echo "✓✅ RBF check passed: Transaction has at least one input with RBF-enabling sequence number"
# Fourth check: Verify transaction has multiple outputs (payment + change)
echo "Checking transaction structure..."
NUM_VOUTS=$(echo "$DECODED_TX" | jq '.vout | length')
if [ "$NUM_VOUTS" -lt 1 ]; then
echo "❌ Error: Transaction doesn't have any outputs!"
exit 1
fi
echo "✓✅ Transaction structure check passed: Transaction has $NUM_VOUTS output(s)"
# Fifth check: Look for a CSV timelock implementation
# Note: The final transaction should have a timelock implementation
echo "Checking for timelock implementation..."
# This is a simplified check - we're looking for any sequence number that could be a timelock
# In a real scenario, we'd check more specifically for the exact timelock requirements
CSV_FOUND=false
for seq in $VIN_SEQUENCES; do
# Look for sequence values that are low numbers (typical for CSV timelock)
# This is a heuristic check since we don't know exactly which input uses CSV
if [ "$seq" -gt 0 ] && [ "$seq" -lt 100 ]; then
CSV_FOUND=true
break
fi
done
# This is a soft check - we'll warn but not fail the build
if [ "$CSV_FOUND" = false ]; then
echo "⚠️ Warning: No obvious CSV timelock implementation found. Sequence numbers don't indicate a typical timelock value."
echo "This might still be correct depending on the specific implementation."
else
echo "✓ Timelock check passed: Found potential CSV timelock implementation"
fi
echo "✅ Success: Advanced Transaction Exercise passed all critical checks!"
echo "Transaction is valid, enables RBF, and has proper structure."