def main(): if len(sys.argv) != 5: print( 'usage: %s <from> <to> <send value sats; negative to send everything> <max num inputs>' % basename(sys.argv[0])) sys.exit(0) fr = s2b(sys.argv[1]) to = sys.argv[2] val = int(sys.argv[3]) max_in = int(sys.argv[4]) if not energi.check_address(to): raise RuntimeError('bad to address: %s' % to) if val < 0: val = None print('Sending ALL NRG to %s.' % (to)) else: print('Sending %f NRG to %s.' % (val / _NRGSAT, to)) addr_d = walletdb.get_address_d(with_change=True) addr_d = {fr: addr_d[fr], 'change': addr_d['change']} bal = balance(addr_d) print('\nCurrent balance: %f NRG. (%d Sat)' % (bal / _NRGSAT, bal)) print('Removing locked outputs.') count = 0 for a in addr_d.keys(): nul = [] for u in addr_d[a].get('utxos', []): if not walletdb.is_locked_txid(u['txid'], u['nout']) and count < max_in: nul.append(u) count += 1 addr_d[a]['utxos'] = nul bal = balance(addr_d) print('\nAvailable balance: %f NRG. (%d Sat)' % (bal / _NRGSAT, bal)) print('Creating transaction.') used_inputs = [] tx = Transaction.create_tx(to, val, addr_d, fee_minimum=4096, used_inputs=used_inputs) print('\n\nTransaction: (%d) %s' % (len(tx), serialize.b2hs(tx))) sys.stdout.write('\nVerifying transaction with energid... ') sys.stdout.flush() print(eel.decode_raw_transaction(serialize.b2hs(tx))) input('\n\nVerified. Press <enter> to transmit ^C to cancel. ') txid = eel.send_raw_transaction(serialize.b2hs(tx)) print('Transmitted. Txid = %s' % (serialize.b2s(txid))) for u in used_inputs: walletdb.remove_unspent_db(u['txid'], u['nout'])
def verify_tx(tx_in, prevout_d = {}): tx = CTransaction(tx_in) if len(tx.vin) == 0: return False # check each input signature for i in range(len(tx.vin)): # get the signature, hash type, and public key (from the standard P2PKH) sd = script.disass(tx.vin[i].scriptSig) if len(sd) != 2 or (sd[0]['opcode'] != 72 and sd[0]['opcode'] != 71) or (sd[1]['opcode'] != 33 and sd[1]['opcode'] != 65): raise RuntimeError('vin[%d] not standard P2PKH; %s' % (i, sd)) signature = sd[0]['data'] hashtype = signature[-1] signature = signature[:-1] public_key = sd[1]['data'] if hashtype not in _hashtype_rev_d.keys(): raise RuntimeError('hashtype in signature not recognized') # get the txid for the output this input refers to txid = serialize.b2hs(tx.vin[i].prevout.hash[::-1]) # get the transaction from prevout dictionary or energid if not provided tx_i_hex = prevout_d[txid]['hex'] if txid in prevout_d else eel.get_hex_transaction(txid) tx_i = CTransaction().deserialize(BytesIO(serialize.hs2b(tx_i_hex))) n = tx.vin[i].prevout.n vout = tx_i.vout[n] vout_spkd = script.disass(vout.scriptPubKey) vout_hpk = vout_spkd[2]['data'] hpk = energi.hash160(public_key) if hpk != vout_hpk: raise RuntimeError('OP_EQUALVERIFY failed: %s != %s' % (serialize.b2hs(hpk), serialize.b2hs(vout_hpk))) sighash = signature_hash(vout.scriptPubKey, tx_in, i, hashtype) pubkey = secp256k1.PublicKey(public_key, raw = True) sig = pubkey.ecdsa_deserialize(signature) if not pubkey.ecdsa_verify(sighash, sig, raw = True): return False # check output address for each #for i in range(len(tx.vout)): # if not script.is_standard(tx.vout[i].scriptPubKey): # print('vout[%d] is not standard' % i) # continue # # sd = script.disass(tx.vout[i].scriptPubKey) # pkh = sd[2]['data'] # addr = energi.address_repr(pkh) return True
def main(): if len(sys.argv) != 3: print('usage: %s <to> <send value sats; negative to send everything>' % basename(sys.argv[0])) sys.exit(0) to = sys.argv[1] val = int(sys.argv[2]) if not energi.check_address(to): raise RuntimeError('bad to address: %s' % to) if val < 0: val = None print('Sending ALL NRG to %s.' % (to)) else: print('Sending %f NRG to %s.' % (val / _NRGSAT, to)) addr_d = walletdb.get_address_d(with_change=True) bal = walletdb.get_balance() print('\nCurrent balance: %f NRG.' % (bal / _NRGSAT)) print('Removing locked outputs.') for a in addr_d: nul = [] for u in addr_d[a].get('utxos', []): if not walletdb.is_locked_txid(u['txid'], u['nout']): nul.append(u) else: print('removing locked: %s' % u) addr_d[a]['utxos'] = nul sys.stdout.write('Creating transaction; confirm on ledger: ') sys.stdout.flush() tx = Transaction.create_tx(to, val, addr_d) print('\n\nTransaction: %s' % serialize.b2hs(tx)) sys.stdout.write('\nVerifying transaction with energid... ') sys.stdout.flush() print(eel.decode_raw_transaction(serialize.b2hs(tx))) input('\n\nVerified. Press <enter> to transmit ^C to cancel. ') txid = eel.send_raw_transaction(serialize.b2hs(tx)) print('Transmitted. Txid = %s' % (serialize.b2s(txid)))
def main(): if len(sys.argv) < 2: print('usage: %s <masternode.conf>' % basename(sys.argv[0])) sys.exit(0) mn_l = parse_conf(sys.argv[1]) mnb_l = [] for mne in mn_l: mnb_l.append(create_mnb(mne)) walletdb.lock_txid(mne['txid'], mne['nout']) smnb = serialize.ser_vector(mnb_l) smnb_hs = serialize.b2hs(smnb) decode(smnb_hs) print('checking with energid:') print(eel.mnb_decode(smnb_hs)) input('Press enter to relay announcement or ^C to abort.') print(eel.mnb_relay(smnb_hs))
def main(): if len(sys.argv) < 4: print( 'usage: %s <to> <send value sats; negative to send everything> <txid:nout> [txid:nout [...]]' % basename(sys.argv[0])) sys.exit(0) to = sys.argv[1] val = int(sys.argv[2]) utxol = [{ 'txid': y[0], 'nout': int(y[1]) } for y in [x.split(':') for x in sys.argv[3:]]] if len(utxol) < 1: raise RuntimeError('must include at least 1 utxo') if not energi.check_address(to): raise RuntimeError('bad address "%s"' % to) if val < 0: val = None print('Sending ALL NRG to %s.' % (to)) else: print('Sending %f NRG to %s.' % (val / _NRGSAT, to)) addr_d = walletdb.get_address_d(with_change=True) print('Searching for utxo%s in walletdb...' % ('s' if len(utxol) > 1 else '')) for addr in addr_d: if 'utxos' in addr_d[addr]: nutxos = [] for u in addr_d[addr]['utxos']: for iu in utxol: if u['txid'] == iu['txid'] and u['nout'] == iu['nout']: nutxos.append(u) break addr_d[addr]['utxos'] = nutxos bal = balance(addr_d) print('\nCurrent balance: %f NRG. (%d Sat)' % (bal / _NRGSAT, bal)) print('Unlocking given inputs: %s' % utxol) input('Press <enter> to unlock, ^C to cancel') for addr in addr_d: if 'utxos' in addr_d[addr]: for u in addr_d[addr]['utxos']: print('unlocking: %s:%d' % (u['txid'], u['nout'])) walletdb.unlock_txid(u['txid'], u['nout']) print('Removing locked outputs.') count = 0 for a in addr_d.keys(): nul = [] for u in addr_d[a].get('utxos', []): if not walletdb.is_locked_txid(u['txid'], u['nout']): nul.append(u) count += 1 addr_d[a]['utxos'] = nul bal = balance(addr_d) print('\nAvailable balance: %f NRG. (%d Sat)' % (bal / _NRGSAT, bal)) print('Creating transaction.') used_inputs = [] tx = Transaction.create_tx(to, val, addr_d, fee_minimum=4096, used_inputs=used_inputs) print('\n\nTransaction: (%d) %s' % (len(tx), serialize.b2hs(tx))) sys.stdout.write('\nVerifying transaction with energid... ') sys.stdout.flush() print(eel.decode_raw_transaction(serialize.b2hs(tx))) input('\n\nVerified. Press <enter> to transmit ^C to cancel. ') txid = eel.send_raw_transaction(serialize.b2hs(tx)) print('Transmitted. Txid = %s' % (serialize.b2s(txid))) for u in used_inputs: walletdb.remove_unspent_db(u['txid'], u['nout'])
def __repr__(self): return 'CMasternodeBroadcast(outpoint = %s, addr = %s, pubkey_collateral = %s, pubkey_masternode = %s, ' \ 'vchSig = %s, sig_time = %d, n_protocol_version = %d, last_ping = %s)' % \ (self.outpoint, self.addr, b2hs(self.pubkey_collateral), b2hs(self.pubkey_masternode), \ b2hs(self.vchSig), self.sig_time, self.n_protocol_version, self.last_ping)
def __repr__(self): return 'CMasternodePing(mn_outpoint = %s, block_hash = %s, sig_time = %d, vchSig = %s, fSentinelIsCurrent = %s, nSentinelVersion = %x, nDaemonVersion = %d)' % \ (self.mn_outpoint, b2hs(self.block_hash), self.sig_time, b2hs(self.vchSig), \ self.fSentinelIsCurrent, self.nSentinelVersion, self.nDaemonVersion)
def __repr__(self): _NRGSAT = 10**8 return 'CTxOut(nValue = %i.%08i, scriptPubKey = %s)' % (self.nValue // _NRGSAT, self.nValue % _NRGSAT, b2hs(self.scriptPubKey))
def __repr__(self): return 'CTxIn(prevout = %s, scriptSig = %s, nSequence = %i)' % (repr(self.prevout), b2hs(self.scriptSig), self.nSequence)
def __repr__(self): return 'COutPoint(hash = %s, n = %i)' % (b2hs(self.hash[::-1]), self.n)
def sign_tx(tx_in, address_d, change_path = None, txid_d = None): tx = CTransaction(tx_in) # First, we need a trusted input blob for each vin[i]. sys.stdout.write('Loading input transactions (%d)... ' % len(tx.vin)); sys.stdout.flush() til = [] for i in range(len(tx.vin)): d = {} # get the txid for the output this input refers to txid = tx.vin[i].prevout.hash txid_hs = serialize.b2hs(txid[::-1]) # and the index into vout n = tx.vin[i].prevout.n # get the transaction from energid tx_i_hex = eel.get_hex_transaction(txid_hs) if txid_d is None else txid_d[txid_hs]['hex'] tx_i = CTransaction().deserialize(BytesIO(serialize.hs2b(tx_i_hex))) # save scriptPubKey for later d['scriptPubKey'] = tx_i.vout[n].scriptPubKey # we'll send this in chunks; the first includes up to vin len buf = struct.pack('<i', tx_i.nVersion) + serialize.ser_compact_size(len(tx_i.vin)) r = ledger.call_get_trusted_input_first(n, buf) if r != b'': raise RuntimeError('get_trusted_input_first: %s' % r) # now send vin for j in range(len(tx_i.vin)): buf = tx_i.vin[j].serialize() r = ledger.call_get_trusted_input_next(buf) if r != b'': raise RuntimeError('get_trusted_input_next: %s' % r) # send len of vout and vout[0] buf = serialize.ser_compact_size(len(tx_i.vout)) + tx_i.vout[0].serialize() r = ledger.call_get_trusted_input_next(buf) if r != b'': raise RuntimeError('get_trusted_input_next (0): %s' % (r)) # send the rest of vout for j in range(1, len(tx_i.vout)): buf = tx_i.vout[j].serialize() r = ledger.call_get_trusted_input_next(buf) if r != b'': raise RuntimeError('get_trusted_input_next (%d): %s' % (j, r)) # send locktime buf = struct.pack('<I', tx_i.nLockTime) r = ledger.call_get_trusted_input_next(buf) if r == b'': raise RuntimeError('bad trusted input response') d['tib'] = r til.append(d) # Second, we need a signature to put in each vin[i].scriptSig. sigs = [] for i in range(len(tx.vin)): tx_i = CTransaction(tx) for v in tx_i.vin: v.scriptSig = b'' tx_i.vin[i].scriptSig = til[i]['scriptPubKey'] # get (hash160) public key we need to sign with if not script.is_standard(til[i]['scriptPubKey']): raise RuntimeError('we can only include P2PKH transactions') sd = script.disass(til[i]['scriptPubKey']) # save for later hpubkey = sd[2]['data'] # again, we'll send the transaction in chunks buf = struct.pack('<i', tx_i.nVersion) + serialize.ser_compact_size(len(tx_i.vin)) + bytes([1, len(til[0]['tib'])]) + til[0]['tib'] + serialize.ser_string(tx_i.vin[0].scriptSig) + struct.pack('<I', tx_i.vin[0].nSequence) r = ledger.call_hash_input_start_first(buf) if b'' != r: raise RuntimeError('hash_input_start_first: %s' % r) for j in range(1, len(tx_i.vin)): buf = bytes([1, len(til[j]['tib'])]) + til[j]['tib'] + serialize.ser_string(tx_i.vin[j].scriptSig) + struct.pack('<I', tx_i.vin[j].nSequence) r = ledger.call_hash_input_start_next(buf) if b'' != r: raise RuntimeError('hash_input_start_next: %s' % r) # okay, all the inputs have been given; now the outputs buf = serialize.ser_vector(tx_i.vout) bufl = [buf[x:x + 200] for x in range(0, len(buf), 200)] # can be broken up arbitrarily # everything but the very last one for b in bufl[:-1]: r = ledger.call_hash_input_finalize_full(b) if b'' != r: raise RuntimeError('hash_input_finalize_full: %s' % r) # register the change path if we have it if change_path is not None: r = ledger.call_hash_input_finalize_full_change(change_path) if b'' != r: raise RuntimeError('hash_input_finalize_full_change: %s' % r) sys.stdout.write('\nSign input %d: ' % (i + 1)); sys.stdout.flush() # now the last part of the outputs r = ledger.call_hash_input_finalize_full_last(bufl[-1]) if r != bytearray(b'\x00\x00'): raise RuntimeError('hash_input_finalize_full: %s' % r) sys.stdout.write('signed'); sys.stdout.flush() # get the address path for the given hashed pubkey addr = energi.address_repr(hpubkey) keypath = energi.serialize_pathd(address_d[addr]) # now sign buf = serialize.hs2b(keypath) + b'\x00' + struct.pack('>I', tx_i.nLockTime) + bytes([_hashtype_d['SIGHASH_ALL']]) r = ledger.call_hash_sign(buf) # last byte is hashtype # save for scriptSig pubkey = address_d[addr]['pubkey'] if 'pubkey' in address_d[addr] else address_d[addr]['public_key'] if energi.hash160(pubkey) != hpubkey: pubkey = energi.compress_public_key(pubkey) if energi.hash160(pubkey) != hpubkey: raise RuntimeError('address confusion') sigs.append({'signature': r, 'pubkey': pubkey}) sys.stdout.write('\n'); sys.stdout.flush() # Finally, everything should be signed. Construct scriptSig for each vin for i in range(len(tx.vin)): tx.vin[i].scriptSig = script.standard_scriptsig(sigs[i]['signature'], sigs[i]['pubkey']) return tx
def calc_sha256(self): self.hash256 = hash256(self.serialize()) self.hash = b2hs(self.hash256) # for display purposes