Support for the Aug 1 2017 UAHF ("Bitcoin Cash", "Bitcoin ABC")
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!
This commit is contained in:
parent
b04650e22f
commit
576d8036c7
6 changed files with 52 additions and 25 deletions
|
|
@ -38,7 +38,7 @@ class g(object):
|
|||
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'
|
||||
|
|
@ -115,6 +115,7 @@ class g(object):
|
|||
('label','keep_label'),
|
||||
('tx_id','info'),
|
||||
('tx_id','terse_info'),
|
||||
('aug1hf','rbf'),
|
||||
('batch','rescan')
|
||||
)
|
||||
cfg_file_opts = (
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ opts_data = {
|
|||
'notes': '\n' + fee_notes + txsign_notes
|
||||
}
|
||||
|
||||
cmd_args = opts.init(opts_data)
|
||||
cmd_args = opts.init(opts_data,add_opts=['aug1hf'])
|
||||
|
||||
c = bitcoin_connection()
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ opts_data = {
|
|||
'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
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ opts_data = {
|
|||
'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
|
||||
|
|
|
|||
66
mmgen/tx.py
66
mmgen/tx.py
|
|
@ -441,6 +441,9 @@ class MMGenTX(MMGenObject):
|
|||
|
||||
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
|
||||
|
|
@ -462,23 +465,34 @@ class MMGenTX(MMGenObject):
|
|||
|
||||
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())
|
||||
ht = ('ALL','ALL|FORKID')[bool(opt.aug1hf)] # sighashtype defaults to 'ALL'
|
||||
ret = c.signrawtransaction(self.hex,sig_data,keys.values(),ht,on_fail='return')
|
||||
|
||||
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']))
|
||||
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'
|
||||
|
|
@ -567,10 +581,24 @@ class MMGenTX(MMGenObject):
|
|||
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'
|
||||
|
|
@ -579,10 +607,6 @@ class MMGenTX(MMGenObject):
|
|||
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',
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue