Skip to content

Commit

Permalink
Support for the Aug 1 2017 UAHF ("Bitcoin Cash", "Bitcoin ABC")
Browse files Browse the repository at this point in the history
Brief instructions for Linux (Windows users may adapt to fit):

    Make a copy of your Bitcoin data directory, including the blockchain and
    your tracking wallet (the blockchain must have been synced last BEFORE
    12:20 UTC Aug. 1).  This can be done as follows:

        $ mkdir ~/.bitcoin-abc
        $ rsync -av ~/.bitcoin/* ~/.bitcoin-abc

    If you messed up and synced your blockchain AFTER the HF, then do the
    following, after which you'll have to sync the ABC chain from scratch:

        $ mkdir ~/.bitcoin-abc
        $ cp ~/.bitcoin/{bitcoin.conf,*wallet*.dat} ~/.bitcoin-abc

    Download the Bitcoin ABC binary, but DON'T let it install automatically.
    Or alternatively, clone the source from Github and compile it yourself:

        Binary: https://download.bitcoinabc.org/0.14.6
        Source: git clone https://github.com/Bitcoin-ABC/bitcoin-abc

    Install the Bitcoin ABC daemon BY HAND into your exec path as 'bitcoind-abc':

        $ sudo cp bitcoind /usr/local/bin/bitcoind-abc

    Start the daemon and let it sync the ABC chain:

        $ bitcoind-abc -datadir=$HOME/.bitcoin-abc -daemon

    Don't forget to always start the ABC daemon with the -datadir argument.
    Otherwise you could trash your Core blockchain!

    Once the HF has activated, you sign or create-sign-send transactions on the
    ABC chain by invoking 'mmgen-txsign' or 'mmgen-txdo' with the --aug1hf
    switch.

    All other commands, including 'mmgen-txcreate' and 'mmgen-txsend', are
    invoked as usual, with no additional command-line switches.  Your address
    balances and unspent outputs will display correctly for whatever chain
    you're on at the moment.

    To switch back to the Core chain, just stop the ABC daemon and restart the
    Core daemon (WITHOUT the -datadir argument).

    After the Aug. 1 HF, Core transactions and ABC transactions will be
    incompatible, as they use an incompatible sighash type.  This prevents
    transactions from being broadcast (and hence replayed) on the wrong chain.
    So if you use the --aug1hf switch on the Core chain, or forget to use it on
    the ABC chain, nothing bad will happen; your sign or send operation will
    just fail with an error message.

    The main danger is forgetting which daemon is running at the moment and
    therefore which chain you're on.  This can be checked on Linux with the
    command `pgrep -a bitcoind` or on Windows by examining the task manager.

    In case you were wondering, all the --aug1hf switch does is perform a few
    sanity checks and call signrawtransaction with 'ALL|FORKID' as the
    'sighashtype' argument.  There's nothing more to it than that!
  • Loading branch information
mmgen committed Jul 31, 2017
1 parent b04650e commit 576d803
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 25 deletions.
3 changes: 2 additions & 1 deletion mmgen/globalvars.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def die(ev=0,s=''):
sys.exit(ev)
# Variables - these might be altered at runtime:

version = '0.9.2'
version = '0.9.299'
release_date = 'July 2017'

proj_name = 'MMGen'
Expand Down Expand Up @@ -115,6 +115,7 @@ def die(ev=0,s=''):
('label','keep_label'),
('tx_id','info'),
('tx_id','terse_info'),
('aug1hf','rbf'),
('batch','rescan')
)
cfg_file_opts = (
Expand Down
2 changes: 1 addition & 1 deletion mmgen/main_txbump.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
'notes': '\n' + fee_notes + txsign_notes
}

cmd_args = opts.init(opts_data)
cmd_args = opts.init(opts_data,add_opts=['aug1hf'])

c = bitcoin_connection()

Expand Down
1 change: 1 addition & 0 deletions mmgen/main_txdo.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
'options': """
-h, --help Print this help message
--, --longhelp Print help message for long options (common options)
-A, --aug1hf Sign transaction for the Aug. 1 2017 UAHF chain
-a, --tx-fee-adj= f Adjust transaction fee by factor 'f' (see below)
-b, --brain-params=l,p Use seed length 'l' and hash preset 'p' for
brainwallet input
Expand Down
1 change: 1 addition & 0 deletions mmgen/main_txsign.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
'options': """
-h, --help Print this help message
--, --longhelp Print help message for long options (common options)
-A, --aug1hf Sign transaction for the Aug. 1 2017 UAHF chain
-b, --brain-params=l,p Use seed length 'l' and hash preset 'p' for
brainwallet input
-d, --outdir= d Specify an alternate directory 'd' for output
Expand Down
68 changes: 46 additions & 22 deletions mmgen/tx.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,9 @@ def sign(self,c,tx_num_str,keys):

self.die_if_incorrect_chain()

if opt.aug1hf and self.has_segwit_inputs():
die(2,yellow("'--aug1hf' option is incompatible with Segwit transaction inputs!"))

if not keys:
msg('No keys. Cannot sign!')
return False
Expand All @@ -462,23 +465,34 @@ def sign(self,c,tx_num_str,keys):

from mmgen.bitcoin import hash256
msg_r('Signing transaction{}...'.format(tx_num_str))
# sighashtype defaults to 'ALL'
sig_tx = c.signrawtransaction(self.hex,sig_data,keys.values())

if sig_tx['complete']:
self.hex = sig_tx['hex']
vmsg('Signed transaction size: {}'.format(len(self.hex)/2))
dt = DeserializedTX(self.hex)
txid = dt['txid']
self.check_sigs(dt)
assert txid == c.decoderawtransaction(self.hex)['txid'], 'txid mismatch (after signing)'
self.btc_txid = BitcoinTxID(txid,on_fail='return')
msg('OK')
return True
else:
msg('failed\nBitcoind returned the following errors:')
msg(repr(sig_tx['errors']))
ht = ('ALL','ALL|FORKID')[bool(opt.aug1hf)] # sighashtype defaults to 'ALL'
ret = c.signrawtransaction(self.hex,sig_data,keys.values(),ht,on_fail='return')

from mmgen.rpc import rpc_error,rpc_errmsg
if rpc_error(ret):
errmsg = rpc_errmsg(ret)
if 'Invalid sighash param' in errmsg:
m = 'This chain does not support the Aug. 1 2017 UAHF.'
m += "\nRe-run 'mmgen-txsign' or 'mmgen-txdo' without the --aug1hf option."
else:
m = errmsg
msg(yellow(m))
return False
else:
if ret['complete']:
self.hex = ret['hex']
vmsg('Signed transaction size: {}'.format(len(self.hex)/2))
dt = DeserializedTX(self.hex)
txid = dt['txid']
self.check_sigs(dt)
assert txid == c.decoderawtransaction(self.hex)['txid'], 'txid mismatch (after signing)'
self.btc_txid = BitcoinTxID(txid,on_fail='return')
msg('OK')
return True
else:
msg('failed\nBitcoind returned the following errors:')
msg(repr(ret['errors']))
return False

def mark_raw(self):
self.desc = 'transaction'
Expand Down Expand Up @@ -567,10 +581,24 @@ def send(self,c,prompt_user=True):
ret = 'deadbeef' * 8
m = 'BOGUS transaction NOT sent: %s'
else:
ret = c.sendrawtransaction(self.hex) # exits on failure
ret = c.sendrawtransaction(self.hex,on_fail='return')
m = 'Transaction sent: %s'

if ret:
from mmgen.rpc import rpc_error,rpc_errmsg
if rpc_error(ret):
errmsg = rpc_errmsg(ret)
if 'Signature must use SIGHASH_FORKID' in errmsg:
m = 'The Aug. 1 2017 UAHF has activated on this chain.'
m += "\nRe-run 'mmgen-txsign' or 'mmgen-txdo' with the --aug1hf option."
elif 'Illegal use of SIGHASH_FORKID' in errmsg:
m = 'The Aug. 1 2017 UAHF is not yet active on this chain.'
m += "\nRe-run 'mmgen-txsign' or 'mmgen-txdo' without the --aug1hf option."
else:
m = errmsg
msg(yellow(m))
msg(red('Send of MMGen transaction {} failed'.format(self.txid)))
return False
else:
if not bogus_send:
assert ret == self.btc_txid, 'txid mismatch (after sending)'
self.desc = 'sent transaction'
Expand All @@ -579,10 +607,6 @@ def send(self,c,prompt_user=True):
self.add_blockcount(c)
return True

# rpc call exits on failure, so we won't get here
msg('Sending of transaction {} failed'.format(self.txid))
return False

def write_txid_to_file(self,ask_write=False,ask_write_default_yes=True):
fn = '%s[%s].%s' % (self.txid,self.send_amt,self.txid_ext)
write_data_to_file(fn,self.btc_txid+'\n','transaction ID',
Expand Down
2 changes: 1 addition & 1 deletion mmgen/txsign.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,4 @@ def txsign(opt,c,tx,seed_files,kl,kal,tx_num_str=''):
if tx.sign(c,tx_num_str,dict(keys)):
return tx
else:
die(3,'failed\nSome keys were missing. Transaction {}could not be signed.'.format(tx_num_str))
die(3,red('Transaction {}could not be signed.'.format(tx_num_str)))

0 comments on commit 576d803

Please sign in to comment.