From b949a66020fd4c021129b77f02c17d4a15e16a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Merwane=20Dra=C3=AF?= Date: Sun, 1 Nov 2020 16:02:13 +0100 Subject: [PATCH 1/2] BTC validation backend --- app/dashboard/sync/btc.py | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/app/dashboard/sync/btc.py b/app/dashboard/sync/btc.py index 7649d8ddec4..8459ac3d310 100644 --- a/app/dashboard/sync/btc.py +++ b/app/dashboard/sync/btc.py @@ -2,8 +2,10 @@ import requests from dashboard.sync.helpers import record_payout_activity, txn_already_used -from oogway import Net +from oogway import Net, validate +import logging +logger = logging.getLogger(__name__) def find_txn_on_btc_explorer(fulfillment, network='mainnet'): funderAddress = fulfillment.bounty.bounty_owner_address @@ -13,21 +15,26 @@ def find_txn_on_btc_explorer(fulfillment, network='mainnet'): n = Net(provider='Blockstream', network=network) txlist = n.txs(funderAddress) - if network == 'mainnet': - blockstream_url = 'https://blockstream.info/api/tx/' + # validate BTC address + is_valid = validate.is_valid_address(funderAddress) + if is_valid == False: + logger.error(f'error: invalid BTC address - {funderAddress}') else: - blockstream_url = 'https://blockstream.info/testnet/api/tx/' - - if txlist != []: - for txn in txlist: - blockstream_response = requests.get(blockstream_url+txn).json() - if ( - blockstream_response['vin'][0]['prevout']['scriptpubkey_address'] == str(funderAddress) and - blockstream_response['vout'][0]['scriptpubkey_address'] == str(payeeAddress) and - float(blockstream_response['vout'][0]['value']) == float(amount) and - not txn_already_used(txn, 'BTC') - ): - return txn + if network == 'mainnet': + blockstream_url = 'https://blockstream.info/api/tx/' + else: + blockstream_url = 'https://blockstream.info/testnet/api/tx/' + + if txlist != []: + for txn in txlist: + blockstream_response = requests.get(blockstream_url+txn).json() + if ( + blockstream_response['vin'][0]['prevout']['scriptpubkey_address'] == str(funderAddress) and + blockstream_response['vout'][0]['scriptpubkey_address'] == str(payeeAddress) and + float(blockstream_response['vout'][0]['value']) == float(amount) and + not txn_already_used(txn, 'BTC') + ): + return txn return None From e40017ea9fd47bbce85bcc841336d657f2698986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Merwane=20Dra=C3=AF?= Date: Sun, 1 Nov 2020 16:45:01 +0100 Subject: [PATCH 2/2] validate BTC address front end --- app/assets/v2/js/pages/new_bounty.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/app/assets/v2/js/pages/new_bounty.js b/app/assets/v2/js/pages/new_bounty.js index 5ab5bff0ce7..0cca2ab2878 100644 --- a/app/assets/v2/js/pages/new_bounty.js +++ b/app/assets/v2/js/pages/new_bounty.js @@ -2,7 +2,12 @@ let appFormBounty; window.addEventListener('dataWalletReady', function(e) { appFormBounty.network = networkName; - appFormBounty.form.funderAddress = selectedAccount; + if (appFormBounty.chainId == 0) { + appFormBounty.form.funderAddress = ""; + } else { + appFormBounty.form.funderAddress = selectedAccount; + } + }, false); Vue.component('v-select', VueSelect.VueSelect); @@ -145,6 +150,19 @@ Vue.mixin({ vm.submitted = true; vm.errors = {}; + // validate BTC address + if (appFormBounty.chainId == 0) { + let ADDRESS_REGEX = new RegExp("^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$"); + let BECH32_REGEX = new RegExp("^bc1[ac-hj-np-zAC-HJ-NP-Z02-9]{11,71}$"); + let valid_legacy = ADDRESS_REGEX.test(vm.form.funderAddress); + let valid_segwit = BECH32_REGEX.test(vm.form.funderAddress); + if (valid_legacy == true || valid_segwit == true){ + // valid + } else { + vm.$set(vm.errors, 'funderAddress', 'Please enter a valid BTC address'); + } + } + if (!vm.form.keywords.length) { vm.$set(vm.errors, 'keywords', 'Please select the prize keywords'); }