set -euo pipefail
+DATA_DIRECTORY=".data"
M=3
N=7
-bitcoin_core_start() {
- log_msg "starting bitcoin core..."
- bitcoind --daemon &> /dev/null
-}
-
-bitcoin_core_ready() {
- set +e
- for i in {1..5}; do
- bitcoin-cli help &> /dev/null
- if [[ $? -eq 0 ]]; then
- set -e
- log_msg "bitcoin core ready"
- return
- fi
- sleep 2
- done
+BITCOIN_CLI="bitcoin-cli -datadir=$DATA_DIRECTORY -chain=regtest"
- log_error "bitcoin_core start failed"
- bitcoin_core_stop
- exit 1
+bitcoin_core_start() {
+ log_info "starting bitcoin core..."
+ mkdir -p "$DATA_DIRECTORY"
+ bitcoind -daemonwait -datadir="$DATA_DIRECTORY" -chain=regtest &> /dev/null
+ log_info "bitcoin core started"
}
bitcoin_core_stop() {
- log_msg "stopping bitcoin core..."
- bitcoin-cli stop &> /dev/null
- log_msg "bitcoin core stopped"
+ log_info "stopping bitcoin core..."
+ local CMD="$BITCOIN_CLI stop"
+ eval "$CMD" &> /dev/null
+ rm -rf "$DATA_DIRECTORY"
+ log_info "bitcoin core stopped"
}
depends() {
echo "$@" >&2
}
+log_info() {
+ echo "$@"
+}
+
log_msg() {
echo "$@"
}
multisig_create() {
+ local DUMPFILE="$DATA_DIRECTORY/descriptors.txt"
+
local DESCRIPTORS="wsh(sortedmulti($M,"
- for((i = 1; i <= $M; i++)); do
- DESCRIPTORS+=wallet_descriptors $i
+ for((i = 1; i <= $N; i++)); do
+ DESCRIPTORS+=$(wallet_descriptors $i)
+ if [[ $i -ne $N ]]; then
+ DESCRIPTORS+=","
+ fi
done
DESCRIPTORS+="))"
+
+ local CMD="echo \"$DESCRIPTORS\" | $BITCOIN_CLI -stdin getdescriptorinfo | jq -j '.descriptor'"
+
+ echo -n '[{"desc": "' > "$DUMPFILE"
+ eval "$CMD" >> "$DUMPFILE"
+ echo -n '", "active": true, "timestamp": "now"},' >> "$DUMPFILE"
+
+ CHANGE_DESCRIPTORS="wsh(sortedmulti($M,"
+
+ for((i = 1; i <= $N; i++)); do
+ CHANGE_DESCRIPTORS+=$(wallet_change_descriptors $i)
+ if [[ $i -ne $N ]]; then
+ CHANGE_DESCRIPTORS+=","
+ fi
+ done
+
+ CHANGE_DESCRIPTORS+="))"
+
+ CMD="echo \"$CHANGE_DESCRIPTORS\" | $BITCOIN_CLI -stdin getdescriptorinfo | jq -j '.descriptor'"
+
+ echo -n '{"desc": "' >> "$DUMPFILE"
+ eval "$CMD" >> "$DUMPFILE"
+ echo -n '", "active": true, "timestamp": "now"}]' >> "$DUMPFILE"
}
network_off() {
}
usage() {
+ cat << EOF
+usage...?
+EOF
+ exit 1
+}
+wallet_change_descriptors() {
+ local CMD="$BITCOIN_CLI -rpcwallet=wallet$1 listdescriptors | jq -j '.descriptors | map(select(.desc | startswith(\"wpkh(\"))) | map(select(.internal == true)) | map(.desc | ltrimstr(\"wpkh(\")) | .[] | split(\")\") | .[0]'"
+ local DESCRIPTORS=$(eval "$CMD")
+ echo "$DESCRIPTORS"
}
wallet_create() {
- bitcoin-cli -named createwallet wallet_name=\"wallet$1\" descriptors=true
+ local CMD="$BITCOIN_CLI -named createwallet wallet_name=wallet$1 descriptors=true"
+ eval "$CMD" > /dev/null
+ log_info "created wallet: wallet$1"
}
wallet_descriptors() {
- local DESCRIPTORS=`bitcoin-cli -rpcwallet=wallet$1 listdescriptors | jq -j '.descriptors | map(select(.desc | startswith("wpkh"))) | map(select(.internal == false)) | map(.desc | ltrimstr("wpkh")) | .[] | split(")") | .[0]'`
-}
-
-wallet_change_descriptors() {
- local DESCRIPTORS=`bitcoin-cli -rpcwallet=wallet$1 listdescriptors | jq -j '.descriptors | map(select(.desc | startswith("wpkh"))) | map(select(.internal == true)) | map(.desc | ltrimstr("wpkh")) | .[] | split(")") | .[0]'`
+ local CMD="$BITCOIN_CLI -rpcwallet=wallet$1 listdescriptors | jq -j '.descriptors | map(select(.desc | startswith(\"wpkh(\"))) | map(select(.internal == false)) | map(.desc | ltrimstr(\"wpkh(\")) | .[] | split(\")\") | .[0]'"
+ local DESCRIPTORS=$(eval "$CMD")
+ echo "$DESCRIPTORS"
}
wallet_dump_descriptors() {
- bitcoin-cli -named -rpcwallet=wallet$1 listdescriptors private=true
+ local DUMPFILE="$DATA_DIRECTORY/wallet$1.descriptors"
+ umask 0077
+ local CMD="$BITCOIN_CLI -named -rpcwallet=wallet$1 listdescriptors private=true"
+ eval "$CMD" > "$DUMPFILE"
+ log_info "dumped descriptors for wallet$1 into $DUMPFILE"
}
wallets() {
done
}
+wallets_clean() {
+ find "$DATA_DIRECTORY" -name "wallet.dat" -exec shred {} \;
+}
+
main() {
depends
bitcoin_core_start
- bitcoin_core_ready
+ wallets "$N"
+
+ multisig_create
- wallets "$M"
+ wallets_clean
bitcoin_core_stop
}