Command line tools for creating and managing Guardian Address signals for the Guardian Address BIP implementation.
A wallet implementation of this draft implementing the protocol exists at https://github.com/bitcoinguardian/electrum
These tools help create the Guardian Address transactions required for the Guardian Address protocol - a Bitcoin coercion resistance mechanism that uses on-chain signalling to lock/unlock wallets remotely.
guardian_signal.py- Creates and broadcasts Guardian lock/unlock transactionsgenerate_guardian_address.py- Generates new Guardian addresses with private keys
Install dependencies:
pip install python-bitcoinutils ecdsa requests bitcoin python-bitcoinlibFirst, create a new Guardian address and private key:
python3 generate_guardian_address.pyThis outputs:
- WIF private key (keep secure and separate from spending wallets)
- Testnet P2WPKH address (your Guardian Address)
Security Note: The Guardian private key must be stored separately from your spending wallet keys to prevent forced signalling attacks.
Send some testnet Bitcoin to the generated Guardian address. You need small amounts (1000-5000 sats) for signal transactions.
Use guardian_signal.py to create lock/unlock signals:
python3 guardian_signal.py \
--wif <guardian_private_key_wif> \
--utxo-txid <funding_txid> \
--utxo-vout <funding_vout> \
--utxo-sats <funding_amount> \
--utxo-addr <guardian_address> \
--to-addr <guardian_address> \
--fee-sats 1000 \
--nonce 1 \
--unlock \
--broadcastpython3 guardian_signal.py \
--wif <guardian_private_key_wif> \
--utxo-txid <previous_txid> \
--utxo-vout 1 \
--utxo-sats <remaining_amount> \
--utxo-addr <guardian_address> \
--to-addr <guardian_address> \
--fee-sats 1000 \
--nonce 2 \
--lock \
--broadcastpython3 guardian_signal.py \
--wif <guardian_private_key_wif> \
--utxo-txid <lock_txid> \
--utxo-vout 1 \
--utxo-sats <remaining_amount> \
--utxo-addr <guardian_address> \
--to-addr <guardian_address> \
--fee-sats 1000 \
--nonce 3 \
--unlock \
--broadcast--wif: WIF private key controlling the Guardian address--utxo-txid: Transaction ID of UTXO to spend--utxo-vout: Output index (usually 1 for change output)--utxo-sats: Amount in the UTXO (in satoshis)--utxo-addr: Guardian address (P2WPKH format)--to-addr: Change address (same as Guardian address)--fee-sats: Transaction fee (recommend 1000+ sats for reliable confirmation)--nonce: Monotonic counter (must increment for each signal)--lock/--unlock: Signal type--broadcast: Actually send the transaction (omit for testing)
Guardian signals embed this data in OP_RETURN outputs:
guardv1.Lock=<true|false>#<nonce>
Examples:
guardv1.Lock=false#1- Unlock/instantiation signalguardv1.Lock=true#2- Lock signalguardv1.Lock=false#3- Unlock signal
For emergency use, you can create pre-signed lock transactions:
- Create the transaction without
--broadcast - Save the raw transaction hex
- Store it securely but separate from keys
- Broadcast later using:
bitcoin-cli sendrawtransaction <hex>
This allows locking wallets even without access to the Guardian private key.
- Key Separation: Guardian keys must be physically separate from spending wallet keys
- Nonce Management: Always increment nonce for each new signal
- Fee Rates: Use sufficient fees (20+ sat/vB) to ensure timely confirmation
- UTXO Tracking: Keep track of which UTXO is available for the next signal
- Pre-signing: Create emergency lock transactions in advance
For increased reliability, create multiple transactions with the same nonce but different fee rates:
# Low fee version
python3 guardian_signal.py --fee-sats 1000 --nonce 2 --lock
# High fee version
python3 guardian_signal.py --fee-sats 3000 --nonce 2 --lockOnly broadcast one - they're mutually exclusive but provide fee flexibility. Duplicate signal nonces are gracefully handled in the wallet.
These tools are configured for testnet only. For mainnet use:
- Change
setup('testnet')tosetup('mainnet')inguardian_signal.py - Change
SelectParams("testnet")toSelectParams("mainnet")ingenerate_guardian_address.py - Use mainnet UTXOs and addresses
- Exercise extreme caution - this is experimental software in support of a BIP draft
Invalid UTXO: Check that the UTXO hasn't been spent and the amount is correct
Nonce errors: Ensure nonce is higher than the previous signal's nonce
Address mismatch: Verify the private key corresponds to the Guardian address
These signals work with Guardian Address compatible wallets like the Guardian plugin for Electrum. Wallets monitor the Guardian address and disable spending when lock signals are detected.
MIT License - same as the Guardian Address BIP implementation.