diff --git a/cyphernodeconf_docker/templates/gatekeeper/api.properties b/cyphernodeconf_docker/templates/gatekeeper/api.properties index 35b0ac4..2a50779 100644 --- a/cyphernodeconf_docker/templates/gatekeeper/api.properties +++ b/cyphernodeconf_docker/templates/gatekeeper/api.properties @@ -53,6 +53,8 @@ action_addtobatch=spender action_batchspend=spender action_deriveindex=spender action_derivepubpath=spender +action_deriveindex_bitcoind=spender +action_derivepubpath_bitcoind=spender action_ln_pay=spender action_ln_newaddr=spender action_ots_stamp=spender diff --git a/cyphernodeconf_docker/templates/installer/config.sh b/cyphernodeconf_docker/templates/installer/config.sh index 65950c5..f54fcd5 100644 --- a/cyphernodeconf_docker/templates/installer/config.sh +++ b/cyphernodeconf_docker/templates/installer/config.sh @@ -33,3 +33,4 @@ OTSCLIENT_DATAPATH=<%= otsclient_datapath %> <% if ( bitcoin_mode==="internal" ) { %> BITCOIN_DATAPATH=<%= bitcoin_datapath %> <% } %> +BITCOIN_NETWORK=<%= net %> diff --git a/proxy_docker/Dockerfile b/proxy_docker/Dockerfile index fb57860..967b4ee 100644 --- a/proxy_docker/Dockerfile +++ b/proxy_docker/Dockerfile @@ -6,7 +6,9 @@ RUN apk add --update --no-cache \ sqlite \ jq \ curl \ - su-exec + su-exec \ + py3-pip \ + xxd WORKDIR ${HOME} @@ -21,7 +23,8 @@ COPY --from=eclipse-mosquitto:1.6-openssl /usr/lib/libssl* /usr/lib/ RUN chmod +x startproxy.sh requesthandler.sh lightning-cli sqlmigrate*.sh waitanyinvoice.sh tests/* \ && chmod o+w . \ - && mkdir db + && mkdir db \ + && pip3 install base58 VOLUME ["${HOME}/db", "/.lightning"] diff --git a/proxy_docker/app/script/bitcoin.sh b/proxy_docker/app/script/bitcoin.sh index 4266046..e851eef 100644 --- a/proxy_docker/app/script/bitcoin.sh +++ b/proxy_docker/app/script/bitcoin.sh @@ -1,9 +1,9 @@ #!/bin/sh . ./trace.sh +. ./sendtobitcoinnode.sh -deriveindex() -{ +deriveindex() { trace "Entering deriveindex()..." local index=${1} @@ -11,8 +11,6 @@ deriveindex() local pub32=$DERIVATION_PUB32 local path=$(echo -e "$DERIVATION_PATH" | sed -En "s/n/${index}/p") - # pub32=$(grep "derivation.pub32" config.properties | cut -d'=' -f2) - # path=$(grep "derivation.path" config.properties | cut -d'=' -f2 | sed -En "s/n/${index}/p") local data="{\"pub32\":\"${pub32}\",\"path\":\"${path}\"}" trace "[deriveindex] data=${data}" @@ -30,8 +28,7 @@ derivepubpath() { return $? } -send_to_pycoin() -{ +send_to_pycoin() { trace "Entering send_to_pycoin()..." local data=${1} @@ -69,3 +66,403 @@ lowercase_if_bech32() { echo "${address}" } + +convert_pub32() { + trace "Entering convert_pub32()..." + + local pub32_from=${1} + local to_type=${2} + local payload + local sha256sum1 + local sha256sum2 + local checksum + local pub32_dest + + case "${to_type}" in + tpub) + versionbytes="043587cf" + ;; + upub) + versionbytes="044a5262" + ;; + vpub) + versionbytes="045f1cf6" + ;; + xpub) + versionbytes="0488b21e" + ;; + ypub) + versionbytes="049d7cb2" + ;; + zpub) + versionbytes="04b24746" + ;; + *) + return 1 + ;; + esac + + payload=$(echo -n "${versionbytes}$(echo -n "${pub32_from}" | base58 -d | xxd -s 4 -ps -c 74 -l 74)") + returncode=$? + trace_rc ${returncode} + trace "[convert_pub32] payload=${payload}" + + # sha256sum 1: + sha256sum1=$(echo -n "${payload}" | xxd -r -ps | sha256sum -b | cut -d' ' -f1 | tr -d "\n") + returncode=$? + trace_rc ${returncode} + trace "[convert_pub32] sha256sum1=${sha256sum1}" + + # sha256sum 2: + sha256sum2=$(echo -n "${sha256sum1}" | xxd -r -ps | sha256sum -b) + returncode=$? + trace_rc ${returncode} + trace "[convert_pub32] sha256sum2=${sha256sum2}" + + # checksum: + checksum=$(echo -n "${sha256sum2}" | xxd -r -ps | xxd -l 4 -ps) + returncode=$? + trace_rc ${returncode} + trace "[convert_pub32] checksum=${checksum}" + + # pub32_dest: + pub32_dest=$(echo -n "${payload}${checksum}" | xxd -r -ps | base58) + returncode=$? + trace_rc ${returncode} + trace "[convert_pub32] pub32_dest=${pub32_dest}" + + echo "${pub32_dest}" +} + +bitcoind_derive_addresses() { + trace "Entering bitcoind_derive_addresses()..." + + local pub32 + local path + local xpub + local index + local path_without_index + local from_n + local to_n + local range + local descfunc + local partialdescriptor + local descriptor + local data + local response + local returncode + + # This is the xpub/ypub/zpub/tpub/upub/vpub + pub32=${1} + trace "[bitcoind_derive_addresses] pub32=${pub32}" + + # This is the path in the form 1/2/8 or 1/2/3-8 + path=${2} + trace "[bitcoind_derive_addresses] path=${path}" + + # This is the pub32 converted to xpub + if [ "${BITCOIN_NETWORK}" = "mainnet" ]; then + xpub=$(convert_pub32 "${pub32}" "xpub") + else + xpub=$(convert_pub32 "${pub32}" "tpub") + fi + returncode=$? + trace_rc ${returncode} + trace "[bitcoind_derive_addresses] xpub=${xpub}" + + # t='1/2/3-8' && echo ${t%/*} && echo ${t##*/} + # 1/2 + # 3-8 + # t='1/2/8' && echo ${t%/*} && echo ${t##*/} + # 1/2 + # 8 + + # This is the index in the form 3-8 or 8 + index=$(echo ${path##*/}) + trace "[bitcoind_derive_addresses] index=${index}" + + # This is the path without the index, like 1/2 + path_without_index=$(echo ${path%/*}) + trace "[bitcoind_derive_addresses] path_without_index=${path_without_index}" + + # This is the starting index, eg for 3-8 it is 3 + from_n=$(echo "${index}" | cut -d '-' -f1) + trace "[bitcoind_derive_addresses] from_n=${from_n}" + + # This is the ending index, eg for 3-8 it is 8 + # For 8 it is 8 + to_n=$(echo "${index}" | cut -d '-' -f2) + trace "[bitcoind_derive_addresses] to_n=${to_n}" + + # If starting and ending index are the same, there's no range to derive, just the index + if [ "${from_n}" -eq "${to_n}" ]; then + partialdescriptor="${xpub}/${path}" + else + range="[${from_n},${to_n}]" + trace "[bitcoind_derive_addresses] range=${range}" + partialdescriptor="${xpub}/${path_without_index}/*" + fi + trace "[bitcoind_derive_addresses] partialdescriptor=${partialdescriptor}" + + # Build the descriptor based on the given pub32 prefix + case ${pub32} in + xpub*|tpub*) descriptor="pkh(${partialdescriptor})" + ;; + ypub*|upub*) descriptor="sh(wpkh(${partialdescriptor}))" + ;; + zpub*|vpub*) descriptor="wpkh(${partialdescriptor})" + ;; + esac + trace "[bitcoind_derive_addresses] descriptor=${descriptor}" + + # Get the descriptor with checksum + data='{"method":"getdescriptorinfo","params":["'${descriptor}'"]}' + trace "[bitcoind_derive_addresses] data=${data}" + descriptor=$(send_to_watcher_node "${data}" | jq -r ".result.descriptor") + returncode=$? + trace_rc ${returncode} + trace "[bitcoind_derive_addresses] descriptor=${descriptor}" + + # Derive the addresses + if [ -z "${range}" ]; then + data='{"method":"deriveaddresses","params":["'${descriptor}'"]}' + else + data='{"method":"deriveaddresses","params":{"descriptor":"'${descriptor}'","range":'${range}'}}' + fi + trace "[bitcoind_derive_addresses] data=${data}" + addresses=$(send_to_watcher_node "${data}" | jq -Mc ".result") + returncode=$? + trace_rc ${returncode} + trace "[bitcoind_derive_addresses] addresses=${addresses}" + + echo "${addresses}" + + return ${returncode} +} + +deriveindex_bitcoind() { + trace "Entering deriveindex_bitcoind()..." + + # index can be in the form n or n-m, ie. 12 or 12-19 + # 12 will only derive one address at index 12 + # 12-19 will derive 8 addresses at indexes 12 to 19 + local index=${1} + trace "[deriveindex_bitcoind] index=${index}" + + local pub32=${DERIVATION_PUB32} + trace "[deriveindex_bitcoind] pub32=${pub32}" + + local path=$(echo -e "$DERIVATION_PATH" | sed -En "s/n/${index}/p") + trace "[deriveindex_bitcoind] path=${path}" + + bitcoind_derive_addresses "${pub32}" "${path}" + + return $? +} + +derivepubpath_bitcoind() { + trace "Entering derivepubpath_bitcoind()..." + + # {"pub32":"tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk","path":"0/25-30"} + + local pub32 + local path + + # This is the xpub/ypub/zpub/tpub/upub/vpub + pub32=$(echo "${1}" | jq -r ".pub32") + trace "[derivepubpath_bitcoind] pub32=${pub32}" + + # This is the path in the form 1/2 or 1/2-8 + path=$(echo "${1}" | jq -r ".path") + trace "[derivepubpath_bitcoind] path=${path}" + + bitcoind_derive_addresses "${pub32}" "${path}" + + return $? +} + +# xpub = P2PKH / P2SH = 1addr or 3addr = pkh() +# ypub = Segwit P2WPKH in P2SH = 3addr = sh(wpkh()) +# Ypub = Segwit Multisig P2WSH in P2SH = 3addr +# zpub = Segwit native P2WPKH = bc1addr = wpkh() +# Zpub = Segwit native Multisig P2WSH = bc1addr + +# tpub = P2PKH / P2SH = nmaddr or 2addr = pkh() +# upub = Segwit P2WPKH in P2SH = 2addr = sh(wpkh()) +# Upub = Segwit Multisig P2WSH in P2SH = 2addr +# vpub = Segwit native P2WPKH = tb1addr = wpkh() +# Vpub = Segwit native Multisig P2WSH = tb1addr + +# https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md +# Output descriptors currently support: +# +# Pay-to-pubkey scripts (P2PK), through the pk function. +# Pay-to-pubkey-hash scripts (P2PKH), through the pkh function. +# Pay-to-witness-pubkey-hash scripts (P2WPKH), through the wpkh function. +# Pay-to-script-hash scripts (P2SH), through the sh function. +# Pay-to-witness-script-hash scripts (P2WSH), through the wsh function. +# Pay-to-taproot outputs (P2TR), through the tr function. +# Multisig scripts, through the multi function. +# Multisig scripts where the public keys are sorted lexicographically, through the sortedmulti function. +# Any type of supported address through the addr function. +# Raw hex scripts through the raw function. +# Public keys (compressed and uncompressed) in hex notation, or BIP32 extended pubkeys with derivation paths. + +# mainnet +# +# kexkey@debian01:~$ bcli deriveaddresses "$(bcli getdescriptorinfo "pkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*)" | jq -r ".descriptor")" "[0,4]" +# [ +# "14qCH92HCyDDBFFZdhDt1WMfrMDYnBFYMF", +# "17igj1BanXgMbEgnLrfYhKHtGPZeBj9CfX", +# "1HcUHrp8YyDfssqXecCnfxd6ZLdF1y2m4d", +# "12iJX7tpCYGYwk7pUNcjMYW2kQgY1yPwNU", +# "13AmGioGrUqYbUVgoX2QA95NdRCbAxMJnS" +# ] +# /pycoin # ku xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL -n BTC -a -s 1/0-4 +# 14qCH92HCyDDBFFZdhDt1WMfrMDYnBFYMF +# 17igj1BanXgMbEgnLrfYhKHtGPZeBj9CfX +# 1HcUHrp8YyDfssqXecCnfxd6ZLdF1y2m4d +# 12iJX7tpCYGYwk7pUNcjMYW2kQgY1yPwNU +# 13AmGioGrUqYbUVgoX2QA95NdRCbAxMJnS +# +# kexkey@debian01:~$ bcli deriveaddresses "$(bcli getdescriptorinfo "sh(wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*))" | jq -r ".descriptor")" "[0,4]" +# [ +# "35JaJ9kTdULF549HwQQX1ffgyhzo6e8oAF", +# "3KoUwSB6e27qMusjdPKKZL5n9Z1dCe9CEb", +# "3AjJQ9k2sFZaXUaJfounfQ69farMtsBY2b", +# "3Coe3nNVbRs5Q4BeJbzGUUwsxMvY5aZC2H", +# "3FBW1Yp5j45dxEnFXvjY2j8P5NqtXUbGQC" +# ] +# /proxy # convert_pub32 xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL ypub +# ypub6ZFS8LErd4QBBVwLiy55q3icFPkSNde7zAnE895MfQsATRevcQsFDpxjadiSgUazAT5PpnAqyQtc3cu6kPGC4fRB5hgpvXVoC4NYx7B2Uih +# /pycoin # ku ypub6ZFS8LErd4QBBVwLiy55q3icFPkSNde7zAnE895MfQsATRevcQsFDpxjadiSgUazAT5PpnAqyQtc3cu6kPGC4fRB5hgpvXVoC4NYx7B2Uih -n BTC -a -s 1/0-4 +# 35JaJ9kTdULF549HwQQX1ffgyhzo6e8oAF +# 3KoUwSB6e27qMusjdPKKZL5n9Z1dCe9CEb +# 3AjJQ9k2sFZaXUaJfounfQ69farMtsBY2b +# 3Coe3nNVbRs5Q4BeJbzGUUwsxMvY5aZC2H +# 3FBW1Yp5j45dxEnFXvjY2j8P5NqtXUbGQC +# +# kexkey@debian01:~$ bcli deriveaddresses "$(bcli getdescriptorinfo "wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*)" | jq -r ".descriptor")" "[0,4]" +# [ +# "bc1q9gzuy9rp0jdsgdxf95zcxgq2shhkrqv0wy2wek", +# "bc1qfxe0s8h2rm94hjta0red37yanjrpc08jxsjzhg", +# "bc1qkcm45vx8svaj728q64wpsrgjks75m74ytsz54h", +# "bc1qztrum7f79x2n9c3ecss5ygxamtxk0k643jyxh7", +# "bc1qzly0x6djdnthpn4kju00tmaglltudc284tpqgx" +# ] +# /proxy # convert_pub32 xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL zpub +# zpub6t5hRzummjwf2o8TZKri38p7RMttKFdcuHJSuXyF3RF3WXU9s52oqtcsbqg2gPEua6CCaFmQS5F9vuWfU5gCru6mx3PFWSKHTnSCLjbc4XQ +# /pycoin # ku zpub6t5hRzummjwf2o8TZKri38p7RMttKFdcuHJSuXyF3RF3WXU9s52oqtcsbqg2gPEua6CCaFmQS5F9vuWfU5gCru6mx3PFWSKHTnSCLjbc4XQ -n BTC -a -s 1/0-4 +# bc1q9gzuy9rp0jdsgdxf95zcxgq2shhkrqv0wy2wek +# bc1qfxe0s8h2rm94hjta0red37yanjrpc08jxsjzhg +# bc1qkcm45vx8svaj728q64wpsrgjks75m74ytsz54h +# bc1qztrum7f79x2n9c3ecss5ygxamtxk0k643jyxh7 +# bc1qzly0x6djdnthpn4kju00tmaglltudc284tpqgx +# +# testnet +# +# debian@preprod-cyphernode:~$ bcli deriveaddresses "$(bcli getdescriptorinfo "pkh(tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk/1/*)" | jq -r ".descriptor")" "[0,4]" +# [ +# "n4Ejeb9EL6dpHQXDX1HqxsWYGedbJtAZot", +# "mou7EK24dBS48u1qUvcyCaKrmUkjGGc84M", +# "mk7Tg1RpQDTCUMrbPS5c5rS2zW5McNT5CD", +# "mntSbET8Us3bjjV1UNRgk4y8KzLCt8NMDV", +# "n1UCqQqjDe8eaPuuTQjCFnn4JKFQ9E4g2v" +# ] +# /pycoin # ku tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk -n BTCY -a -s 1/0-4 +# n4Ejeb9EL6dpHQXDX1HqxsWYGedbJtAZot +# mou7EK24dBS48u1qUvcyCaKrmUkjGGc84M +# mk7Tg1RpQDTCUMrbPS5c5rS2zW5McNT5CD +# mntSbET8Us3bjjV1UNRgk4y8KzLCt8NMDV +# n1UCqQqjDe8eaPuuTQjCFnn4JKFQ9E4g2v +# +# debian@preprod-cyphernode:~$ bcli deriveaddresses "$(bcli getdescriptorinfo "sh(wpkh(tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk/1/*))" | jq -r ".descriptor")" "[0,4]" +# [ +# "2N3RtGVRuJc8zUrD2zqTmgcBakaGVEvyLRx", +# "2N1VKRFpQVRetXGcJh4DTWVWWYJHZSTLU3x", +# "2MvXSh2YAaZkDM2qkPvwzNkizU85qSgU5wa", +# "2MwLhxRYQejtNRh9VJ4USH9oCBXVbe3oPkj", +# "2N3yNaASJT3uHoDV5RTyATFS48K32TDjYrp" +# ] +# /proxy # convert_pub32 tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk upub +# upub57Wa4MvRPNyAijHCMmZ1qAk3LfAB7bQpHQA3djER2gXkS2F5vrDb1ydWmXUVqUHRBpKRfQSucSr1xeWfGtS2qF9NnCHWnCLzMD3GofE1xrd +# /pycoin # ku upub57Wa4MvRPNyAijHCMmZ1qAk3LfAB7bQpHQA3djER2gXkS2F5vrDb1ydWmXUVqUHRBpKRfQSucSr1xeWfGtS2qF9NnCHWnCLzMD3GofE1xrd -n BTCY -a -s 1/0-4 +# 2N3RtGVRuJc8zUrD2zqTmgcBakaGVEvyLRx +# 2N1VKRFpQVRetXGcJh4DTWVWWYJHZSTLU3x +# 2MvXSh2YAaZkDM2qkPvwzNkizU85qSgU5wa +# 2MwLhxRYQejtNRh9VJ4USH9oCBXVbe3oPkj +# 2N3yNaASJT3uHoDV5RTyATFS48K32TDjYrp +# +# debian@preprod-cyphernode:~$ bcli deriveaddresses "$(bcli getdescriptorinfo "wpkh(tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk/1/*)" | jq -r ".descriptor")" "[0,4]" +# [ +# "tb1qlyu6umpkk0jhr33j90h3ff5qpw6t25y5f6huzp", +# "tb1qt0cemjuvrkj2hxhwm9769hdukfu4zfdfkknxxe", +# "tb1qxfnjka657mymehg92k3ekrmqk9289h7hvvaxaj", +# "tb1q2rvncazgrvzllm0v5qc4nrldu4u2vkyr27ujx4", +# "tb1qmtwk0h8hht6tqvrcwwzem48x54042fxelk8x52" +# ] +# /proxy # convert_pub32 tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk vpub +# vpub5SLqN2bLY4Wea2UKC8Le3FqYWdJd4DQKCWgGR88JQgudV84KBWP9e3HenjS5qNwLbTSEQt3U57CZqw8Dzar3dUpyeXywN7AUcw6vCDFXgMy +# /pycoin # ku vpub5SLqN2bLY4Wea2UKC8Le3FqYWdJd4DQKCWgGR88JQgudV84KBWP9e3HenjS5qNwLbTSEQt3U57CZqw8Dzar3dUpyeXywN7AUcw6vCDFXgMy -n BTCY -a -s 1/0-4 +# tb1qlyu6umpkk0jhr33j90h3ff5qpw6t25y5f6huzp +# tb1qt0cemjuvrkj2hxhwm9769hdukfu4zfdfkknxxe +# tb1qxfnjka657mymehg92k3ekrmqk9289h7hvvaxaj +# tb1q2rvncazgrvzllm0v5qc4nrldu4u2vkyr27ujx4 +# tb1qmtwk0h8hht6tqvrcwwzem48x54042fxelk8x52 +# +# regtest +# +# kexkey@AlcodaZ-2 dist % docker exec -it $(docker ps -q -f "name=cyphernode_bitcoin") bitcoin-cli deriveaddresses "$(docker exec -it $(docker ps -q -f "name=cyphernode_bitcoin") bitcoin-cli getdescriptorinfo "pkh(tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk/1/*)" | jq -r ".descriptor")" "[0,4]" +# [ +# "n4Ejeb9EL6dpHQXDX1HqxsWYGedbJtAZot", +# "mou7EK24dBS48u1qUvcyCaKrmUkjGGc84M", +# "mk7Tg1RpQDTCUMrbPS5c5rS2zW5McNT5CD", +# "mntSbET8Us3bjjV1UNRgk4y8KzLCt8NMDV", +# "n1UCqQqjDe8eaPuuTQjCFnn4JKFQ9E4g2v" +# ] +# /pycoin # ku tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk -n BTCY -a -s 1/0-4 +# +# kexkey@AlcodaZ-2 dist % docker exec -it $(docker ps -q -f "name=cyphernode_bitcoin") bitcoin-cli deriveaddresses "$(docker exec -it $(docker ps -q -f "name=cyphernode_bitcoin") bitcoin-cli getdescriptorinfo "sh(wpkh(tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk/1/*))" | jq -r ".descriptor")" "[0,4]" +# [ +# "2N3RtGVRuJc8zUrD2zqTmgcBakaGVEvyLRx", +# "2N1VKRFpQVRetXGcJh4DTWVWWYJHZSTLU3x", +# "2MvXSh2YAaZkDM2qkPvwzNkizU85qSgU5wa", +# "2MwLhxRYQejtNRh9VJ4USH9oCBXVbe3oPkj", +# "2N3yNaASJT3uHoDV5RTyATFS48K32TDjYrp" +# ] +# kexkey@AlcodaZ-2 dist % docker exec -it $(docker ps -q -f "name=cyphernode_bitcoin") bitcoin-cli deriveaddresses "$(docker exec -it $(docker ps -q -f "name=cyphernode_bitcoin") bitcoin-cli getdescriptorinfo "wpkh(tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk/1/*)" | jq -r ".descriptor")" "[0,4]" +# [ +# "bcrt1qlyu6umpkk0jhr33j90h3ff5qpw6t25y5tnw34g", +# "bcrt1qt0cemjuvrkj2hxhwm9769hdukfu4zfdf5l2t3s", +# "bcrt1qxfnjka657mymehg92k3ekrmqk9289h7hw9yt2m", +# "bcrt1q2rvncazgrvzllm0v5qc4nrldu4u2vkyrgh9l3u", +# "bcrt1qmtwk0h8hht6tqvrcwwzem48x54042fxeal7trr" +# ] + +############################################################## +############################################################## + +# docker exec -it $(docker ps -q -f "name=cyphernode_proxy\.") curl -d '{"pub32":"tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk","path":"0/26-30"}' localhost:8888/derivepubpath +# {"addresses":[{"address":"mmaVh4SYCQhSmLWwFz7TuJ6WrQRYy8ertu"},{"address":"msriobrSwkReTfzvQr78de6RBfcbVCDxmX"},{"address":"mp377o3ifAGT5hnDBFjzmm8dFKEC9Cr4ct"},{"address":"mkxWm27kekHJC2kH1HgiT18xHrLMriZ3rc"},{"address":"mwoQwJckE6otryPNyeYwknsMCwjgyNWdjh"}]} +# +# docker exec -it $(docker ps -q -f "name=cyphernode_proxy\.") curl -d '{"pub32":"tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk","path":"0/26-30"}' localhost:8888/derivepubpath_bitcoind +# ["mmaVh4SYCQhSmLWwFz7TuJ6WrQRYy8ertu","msriobrSwkReTfzvQr78de6RBfcbVCDxmX","mp377o3ifAGT5hnDBFjzmm8dFKEC9Cr4ct","mkxWm27kekHJC2kH1HgiT18xHrLMriZ3rc","mwoQwJckE6otryPNyeYwknsMCwjgyNWdjh"] +# +# docker exec -it $(docker ps -q -f "name=cyphernode_proxy\.") curl -d '{"pub32":"tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk","path":"0/30"}' localhost:8888/derivepubpath +# {"addresses":[{"address":"mwoQwJckE6otryPNyeYwknsMCwjgyNWdjh"}]} +# +# docker exec -it $(docker ps -q -f "name=cyphernode_proxy\.") curl -d '{"pub32":"tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk","path":"0/30"}' localhost:8888/derivepubpath_bitcoind +# ["mwoQwJckE6otryPNyeYwknsMCwjgyNWdjh"] +# +# docker exec -it $(docker ps -q -f "name=cyphernode_proxy\.") curl localhost:8888/deriveindex/26-30 +# {"addresses":[{"address":"2NFLhFghAPKEPuZCKoeXYYxuaBxhKXbmhBV"},{"address":"2N7gepbQtRM5Hm4PTjvGadj9wAwEwnAsKiP"},{"address":"2Mth8XDZpXkY9d95tort8HYEAuEesow2tF6"},{"address":"2MwqEmAXhUw6H7bJwMhD13HGWVEj2HgFiNH"},{"address":"2N2Y4BVRdrRFhweub2ehHXveGZC3nryMEJw"}]} +# +# docker exec -it $(docker ps -q -f "name=cyphernode_proxy\.") curl localhost:8888/deriveindex_bitcoind/26-30 +# ["2NFLhFghAPKEPuZCKoeXYYxuaBxhKXbmhBV","2N7gepbQtRM5Hm4PTjvGadj9wAwEwnAsKiP","2Mth8XDZpXkY9d95tort8HYEAuEesow2tF6","2MwqEmAXhUw6H7bJwMhD13HGWVEj2HgFiNH","2N2Y4BVRdrRFhweub2ehHXveGZC3nryMEJw"] +# +# docker exec -it $(docker ps -q -f "name=cyphernode_proxy\.") curl localhost:8888/deriveindex/30 +# {"addresses":[{"address":"2N2Y4BVRdrRFhweub2ehHXveGZC3nryMEJw"}]} +# +# docker exec -it $(docker ps -q -f "name=cyphernode_proxy\.") curl localhost:8888/deriveindex_bitcoind/30 +# ["2N2Y4BVRdrRFhweub2ehHXveGZC3nryMEJw"] +# diff --git a/proxy_docker/app/script/requesthandler.sh b/proxy_docker/app/script/requesthandler.sh index 4119580..cba8db8 100644 --- a/proxy_docker/app/script/requesthandler.sh +++ b/proxy_docker/app/script/requesthandler.sh @@ -607,6 +607,24 @@ main() { response_to_client "${response}" ${?} break ;; + deriveindex_bitcoind) + # curl GET http://192.168.111.152:8080/deriveindex_bitcoind/25-30 + # curl GET http://192.168.111.152:8080/deriveindex_bitcoind/34 + + response=$(deriveindex_bitcoind "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)") + response_to_client "${response}" ${?} + break + ;; + derivepubpath_bitcoind) + # POST http://192.168.111.152:8080/derivepubpath_bitcoind + # BODY {"pub32":"tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk","path":"0/25-30"} + # BODY {"pub32":"upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb","path":"0/25-30"} + # BODY {"pub32":"vpub5SLqN2bLY4WeZF3kL4VqiWF1itbf3A6oRrq9aPf16AZMVWYCuN9TxpAZwCzVgW94TNzZPNc9XAHD4As6pdnExBtCDGYRmNJrcJ4eV9hNqcv","path":"0/25-30"} + + response=$(derivepubpath_bitcoind "${line}") + response_to_client "${response}" ${?} + break + ;; getmempoolinfo) # curl GET http://192.168.111.152:8080/getmempoolinfo diff --git a/proxy_docker/app/tests/test-derive.sh b/proxy_docker/app/tests/test-derive.sh new file mode 100755 index 0000000..40db98c --- /dev/null +++ b/proxy_docker/app/tests/test-derive.sh @@ -0,0 +1,92 @@ +#!/bin/sh + +test_derive() { + local address + local address1 + local address2 + local address3 + local response + local transaction + + # deriveindex + # (GET) http://proxy:8888/deriveindex/25-30 + # {"addresses":[{"address":"2N6Q9kBcLtNswgMSLSQ5oduhbctk7hxEJW8"},{"address":"2NFLhFghAPKEPuZCKoeXYYxuaBxhKXbmhBV"},{"address":"2N7gepbQtRM5Hm4PTjvGadj9wAwEwnAsKiP"},{"address":"2Mth8XDZpXkY9d95tort8HYEAuEesow2tF6"},{"address":"2MwqEmAXhUw6H7bJwMhD13HGWVEj2HgFiNH"},{"address":"2N2Y4BVRdrRFhweub2ehHXveGZC3nryMEJw"}]} + + echo "Testing deriveindex..." + response=$(curl -s proxy:8888/deriveindex/25-30) + echo "response=${response}" + local nbaddr=$(echo "${response}" | jq ".addresses | length") + if [ "${nbaddr}" -ne "6" ]; then + exit 130 + fi + address=$(echo "${response}" | jq ".addresses[2].address" | tr -d '\"') + if [ "${address}" != "2N7gepbQtRM5Hm4PTjvGadj9wAwEwnAsKiP" ]; then + exit 140 + fi + echo "Tested deriveindex." + + # derivepubpath + # (GET) http://proxy:8888/derivepubpath + # BODY {"pub32":"upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb","path":"0/25-30"} + # {"addresses":[{"address":"2N6Q9kBcLtNswgMSLSQ5oduhbctk7hxEJW8"},{"address":"2NFLhFghAPKEPuZCKoeXYYxuaBxhKXbmhBV"},{"address":"2N7gepbQtRM5Hm4PTjvGadj9wAwEwnAsKiP"},{"address":"2Mth8XDZpXkY9d95tort8HYEAuEesow2tF6"},{"address":"2MwqEmAXhUw6H7bJwMhD13HGWVEj2HgFiNH"},{"address":"2N2Y4BVRdrRFhweub2ehHXveGZC3nryMEJw"}]} + + echo "Testing derivepubpath..." + response=$(curl -s -H "Content-Type: application/json" -d "{\"pub32\":\"upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb\",\"path\":\"0/25-30\"}" proxy:8888/derivepubpath) + echo "response=${response}" + local nbaddr=$(echo "${response}" | jq ".addresses | length") + if [ "${nbaddr}" -ne "6" ]; then + exit 150 + fi + address=$(echo "${response}" | jq ".addresses[2].address" | tr -d '\"') + if [ "${address}" != "2N7gepbQtRM5Hm4PTjvGadj9wAwEwnAsKiP" ]; then + exit 160 + fi + echo "Tested derivepubpath." + + # deriveindex_bitcoind + # (GET) http://proxy:8888/deriveindex_bitcoind/25-30 + # ["2N6Q9kBcLtNswgMSLSQ5oduhbctk7hxEJW8","2NFLhFghAPKEPuZCKoeXYYxuaBxhKXbmhBV","2N7gepbQtRM5Hm4PTjvGadj9wAwEwnAsKiP","2Mth8XDZpXkY9d95tort8HYEAuEesow2tF6","2MwqEmAXhUw6H7bJwMhD13HGWVEj2HgFiNH","2N2Y4BVRdrRFhweub2ehHXveGZC3nryMEJw"] + + echo "Testing deriveindex_bitcoind..." + response=$(curl -s proxy:8888/deriveindex_bitcoind/25-30) + echo "response=${response}" + local nbaddr=$(echo "${response}" | jq ". | length") + if [ "${nbaddr}" -ne "6" ]; then + exit 130 + fi + address=$(echo "${response}" | jq ".[2]" | tr -d '\"') + if [ "${address}" != "2N7gepbQtRM5Hm4PTjvGadj9wAwEwnAsKiP" ]; then + exit 140 + fi + echo "Tested deriveindex_bitcoind." + + # derivepubpath_bitcoind + # (GET) http://proxy:8888/derivepubpath_bitcoind + # BODY {"pub32":"upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb","path":"0/25-30"} + # ["2N6Q9kBcLtNswgMSLSQ5oduhbctk7hxEJW8","2NFLhFghAPKEPuZCKoeXYYxuaBxhKXbmhBV","2N7gepbQtRM5Hm4PTjvGadj9wAwEwnAsKiP","2Mth8XDZpXkY9d95tort8HYEAuEesow2tF6","2MwqEmAXhUw6H7bJwMhD13HGWVEj2HgFiNH","2N2Y4BVRdrRFhweub2ehHXveGZC3nryMEJw"] + + echo "Testing derivepubpath_bitcoind..." + response=$(curl -s -H "Content-Type: application/json" -d "{\"pub32\":\"upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb\",\"path\":\"0/25-30\"}" proxy:8888/derivepubpath_bitcoind) + echo "response=${response}" + local nbaddr=$(echo "${response}" | jq ". | length") + if [ "${nbaddr}" -ne "6" ]; then + exit 150 + fi + address=$(echo "${response}" | jq ".[2]" | tr -d '\"') + if [ "${address}" != "2N7gepbQtRM5Hm4PTjvGadj9wAwEwnAsKiP" ]; then + exit 160 + fi + echo "Tested derivepubpath_bitcoind." + + # deriveindex_bitcoind and derivepubpath_bitcoind faster derivation? + echo -e "\nDeriving 500 addresses with derivepubpath (Pycoin)..." + time curl -s -H "Content-Type: application/json" -d "{\"pub32\":\"upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb\",\"path\":\"0/0-499\"}" proxy:8888/derivepubpath > /dev/null + + echo -e "\nDeriving 500 addresses with derivepubpath_bitcoind (Bitcoin Core)..." + time curl -s -H "Content-Type: application/json" -d "{\"pub32\":\"upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb\",\"path\":\"0/0-499\"}" proxy:8888/derivepubpath_bitcoind > /dev/null + +} + +apk add curl jq + +test_derive diff --git a/pycoin_docker/script/pycoin.sh b/pycoin_docker/script/pycoin.sh index 4e3e387..5c46990 100644 --- a/pycoin_docker/script/pycoin.sh +++ b/pycoin_docker/script/pycoin.sh @@ -28,7 +28,7 @@ derive() { for address in ${result} do if ${notfirst}; then - echo "," + echo -n "," else notfirst=true fi