Exemplo n.º 1
0
	def validate(self, provider=None):
		if self.merkle_root != self.build_merkle_root():
			raise ValueError("calculated merkle_root %s does not match stated merkle_root %s from header" % (self.build_merkle_root(), self.merkle_root))

		self.total_out = 0
		if provider is not None:
			print "Doing full, online validation."
			self.total_in = 0
			self.total_fee = 0
		else:
			print "Doing limited, offline validation."

		print "Validating %d transactions" % len(self.batchable_txs)
		for tx_index, tx in enumerate(self.batchable_txs):
			print "\n\nValidating tx#%d - %s" % (tx_index+1, tx.id())
			print "- Total out", tx.total_out()
			self.total_out += tx.total_out()
			if provider:
				print "Fetching %d UTXO..." % len(tx.txs_in)
				for idx, tx_in in enumerate(tx.txs_in):
					unspent_tx = provider.get_tx(tx_in.previous_hash)
					tx.unspents.append(unspent_tx.txs_out[tx_in.previous_index])

				print "- Total in", tx.total_in()
				self.total_in += tx.total_in()

				print "- Fee", tx.fee()
				self.total_fee += tx.fee()

				print "- Transaction Size", len(tx.as_hex()) // 2
				print "- Recommended Fee for Size ", tx_fee.recommended_fee_for_tx(tx)
				if tx.fee() > 100000 and tx.fee() > 2 * tx_fee.recommended_fee_for_tx(tx):
					raise ValueError("Very high fee in transaction %s" % tx.id())
				print "- Fee Percent", (tx.fee() * 100.00 / tx.total_out())
				print "- Bad Signatures", tx.bad_signature_count(), "of", len(tx.txs_in)
Exemplo n.º 2
0
def check_fees(tx):
    total_in, total_out = tx.total_in(), tx.total_out()
    actual_tx_fee = total_in - total_out
    recommended_tx_fee = tx_fee.recommended_fee_for_tx(tx)
    print(
        "warning: transaction fees recommendations casually calculated and estimates may be incorrect",
        file=sys.stderr)
    if actual_tx_fee > recommended_tx_fee:
        print(
            "warning: transaction fee of %s exceeds expected value of %s mBTC"
            % (satoshi_to_mbtc(actual_tx_fee),
               satoshi_to_mbtc(recommended_tx_fee)),
            file=sys.stderr)
    elif actual_tx_fee < 0:
        print("not enough source coins (%s mBTC) for destination (%s mBTC)."
              " Short %s mBTC" %
              (satoshi_to_mbtc(total_in), satoshi_to_mbtc(total_out),
               satoshi_to_mbtc(-actual_tx_fee)),
              file=sys.stderr)
    elif actual_tx_fee < recommended_tx_fee:
        print("warning: transaction fee lower than (casually calculated)"
              " expected value of %s mBTC, transaction might not propogate" %
              satoshi_to_mbtc(recommended_tx_fee),
              file=sys.stderr)
    return actual_tx_fee
Exemplo n.º 3
0
    def send(self, ddestination_address, dcolourid=None):
        self.colordata.update()

        coins_to = []
        total_spent = 0
        for daa in [ddestination_address]:
            address, amount = daa[0], daa[1]
            amount = btc_to_satoshi(amount)
            total_spent += amount
            coins_to.append((amount, address))

        selected_utxos, total_value = self.selectUTXOs(self.getAllUTXOs(), dcolourid, total_spent)
        change = (total_value - total_spent) - 10000
        if change >= 1:
            coins_to.append((change, self.addresses[0].pubkey))

        coins_from = [utxo.get_pycoin_coin_source() for utxo in selected_utxos]
        secret_exponents = [encoding.wif_to_secret_exponent(address.privkey) for address in self.addresses]

        unsigned_tx = UnsignedTx.standard_tx(coins_from, coins_to)
        solver = SecretExponentSolver(secret_exponents)
        new_tx = unsigned_tx.sign(solver)
        s = io.BytesIO()
        new_tx.stream(s)
        tx_bytes = s.getvalue()
        tx_hex = binascii.hexlify(tx_bytes).decode("utf8")
        recommended_tx_fee = tx_fee.recommended_fee_for_tx(new_tx)

        print tx_hex

        URL = "http://blockchain.info/pushtx"
        urllib2.urlopen(URL, data=tx_hex)
Exemplo n.º 4
0
def check_fees(unsigned_tx):
    total_value, total_spent = calculate_fees(unsigned_tx)
    actual_tx_fee = total_value - total_spent
    recommended_tx_fee = tx_fee.recommended_fee_for_tx(unsigned_tx)
    if actual_tx_fee > recommended_tx_fee:
        print("warning: transaction fee of exceeds expected value of %s BTC" % satoshi_to_btc(recommended_tx_fee))
    elif actual_tx_fee < 0:
        print("not enough source coins (%s BTC) for destination (%s BTC). Short %s BTC" % (satoshi_to_btc(total_value), satoshi_to_btc(total_spent), satoshi_to_btc(-actual_tx_fee)))
    elif actual_tx_fee < recommended_tx_fee:
        print("warning: transaction fee lower than (casually calculated) expected value of %s BTC, transaction might not propogate" % satoshi_to_btc(recommended_tx_fee))
    return actual_tx_fee
Exemplo n.º 5
0
def check_fees(unsigned_tx):
    total_value, total_spent = calculate_fees(unsigned_tx)
    actual_tx_fee = total_value - total_spent
    recommended_tx_fee = tx_fee.recommended_fee_for_tx(unsigned_tx)
    if actual_tx_fee > recommended_tx_fee:
        print("warning: transaction fee of exceeds expected value of %s BTC" % satoshi_to_btc(recommended_tx_fee))
    elif actual_tx_fee < 0:
        print("not enough source coins (%s BTC) for destination (%s BTC). Short %s BTC" % (satoshi_to_btc(total_value), satoshi_to_btc(total_spent), satoshi_to_btc(-actual_tx_fee)))
    elif actual_tx_fee < recommended_tx_fee:
        print("warning: transaction fee lower than (casually calculated) expected value of %s BTC, transaction might not propogate" % satoshi_to_btc(recommended_tx_fee))
    return actual_tx_fee
Exemplo n.º 6
0
def main():
    parser = argparse.ArgumentParser(description="Create a Bitcoin transaction.")

    parser.add_argument('-s', "--source-address", help='source Bitcoin address', required=True, nargs="+", metavar='source_address')
    parser.add_argument('-d', "--destination-address", help='destination Bitcoin address/amount', required=True, metavar='dest_address/amount_in_btc', nargs="+")
    parser.add_argument('-f', "--wif-file", help='WIF items for source Bitcoin addresses', required=True, metavar="path-to-WIF-values", type=argparse.FileType('r'))
    args = parser.parse_args()

    total_value = 0
    coins_from = []
    for bca in args.source_address:
        coins_sources = blockchain_info.coin_sources_for_address(bca)
        coins_from.extend(coins_sources)
        total_value += sum(cs[-1].coin_value for cs in coins_sources)

    secret_exponents = []
    for l in args.wif_file:
        print l
        secret_exponents.append(encoding.wif_to_secret_exponent(l[:-1]))

    coins_to = []
    total_spent = 0
    for daa in args.destination_address:
        address, amount = daa.split("/")
        amount = btc_to_satoshi(amount)
        total_spent += amount
        coins_to.append((amount, address))

    actual_tx_fee = total_value - total_spent
    if actual_tx_fee < 0:
        print("not enough source coins (%s BTC) for destination (%s BTC). Short %s BTC" % (satoshi_to_btc(total_value), satoshi_to_btc(total_spent), satoshi_to_btc(-actual_tx_fee)))
        sys.exit(1)

    print("transaction fee: %s BTC" % satoshi_to_btc(actual_tx_fee))
    unsigned_tx = UnsignedTx.standard_tx(coins_from, coins_to)
    solver = SecretExponentSolver(secret_exponents)
    new_tx = unsigned_tx.sign(solver)
    s = io.BytesIO()
    new_tx.stream(s)
    tx_bytes = s.getvalue()
    tx_hex = binascii.hexlify(tx_bytes).decode("utf8")
    recommended_tx_fee = tx_fee.recommended_fee_for_tx(new_tx)
    if actual_tx_fee > recommended_tx_fee:
        print("warning: transaction fee of exceeds expected value of %s BTC" % satoshi_to_btc(recommended_tx_fee))
    elif actual_tx_fee < recommended_tx_fee:
        print("warning: transaction fee lower than (casually calculated) expected value of %s BTC, transaction might not propogate" % satoshi_to_btc(recommended_tx_fee))
    print("copy the following hex to http://blockchain.info/pushtx to put the transaction on the network:\n")
    print(tx_hex)
Exemplo n.º 7
0
def check_fees(tx):
    total_in, total_out = tx.total_in(), tx.total_out()
    actual_tx_fee = total_in - total_out
    recommended_tx_fee = tx_fee.recommended_fee_for_tx(tx)
    print("warning: transaction fees recommendations casually calculated and estimates may be incorrect",
          file=sys.stderr)
    if actual_tx_fee > recommended_tx_fee:
        print("warning: transaction fee of %s exceeds expected value of %s mBTC" %
              (satoshi_to_mbtc(actual_tx_fee), satoshi_to_mbtc(recommended_tx_fee)),
              file=sys.stderr)
    elif actual_tx_fee < 0:
        print("not enough source coins (%s mBTC) for destination (%s mBTC)."
              " Short %s mBTC" %
              (satoshi_to_mbtc(total_in),
               satoshi_to_mbtc(total_out), satoshi_to_mbtc(-actual_tx_fee)),
              file=sys.stderr)
    elif actual_tx_fee < recommended_tx_fee:
        print("warning: transaction fee lower than (casually calculated)"
              " expected value of %s mBTC, transaction might not propogate" %
              satoshi_to_mbtc(recommended_tx_fee), file=sys.stderr)
    return actual_tx_fee
Exemplo n.º 8
0
    def send(self, ddestination_address, dcolourid=None):
        self.colordata.update()

        coins_to = []
        total_spent = 0
        for daa in [ddestination_address]:
            address, amount = daa[0], daa[1]
            amount = btc_to_satoshi(amount)
            total_spent += amount
            coins_to.append((amount, address))

        selected_utxos, total_value = self.selectUTXOs(self.getAllUTXOs(),
                                                       dcolourid, total_spent)
        change = (total_value - total_spent) - 10000
        if change >= 1:
            coins_to.append((change, self.addresses[0].pubkey))

        coins_from = [utxo.get_pycoin_coin_source() for utxo in selected_utxos]
        secret_exponents = [
            encoding.wif_to_secret_exponent(address.privkey)
            for address in self.addresses
        ]

        unsigned_tx = UnsignedTx.standard_tx(coins_from, coins_to)
        solver = SecretExponentSolver(secret_exponents)
        new_tx = unsigned_tx.sign(solver)
        s = io.BytesIO()
        new_tx.stream(s)
        tx_bytes = s.getvalue()
        tx_hex = binascii.hexlify(tx_bytes).decode("utf8")
        recommended_tx_fee = tx_fee.recommended_fee_for_tx(new_tx)

        print tx_hex

        URL = "http://blockchain.info/pushtx"
        urllib2.urlopen(URL, data=tx_hex)
Exemplo n.º 9
0
def build_psbt(ctx, xfp, addrs, pubkey=None, xpubs=None, redeem=None):
    locals().update(ctx.obj)
    payout_address = ctx.obj['payout_address']
    out_psbt = ctx.obj['output_psbt']

    if pubkey:
        assert len(addrs) == 1  # can only be single addr in that case
        assert len(pubkey) == 33

    spending = []
    total = 0
    psbt = BasicPSBT()

    for path, addr in addrs:
        print(f"addr: {path} => {addr} ... ", end='')

        rr = explora('address', addr, 'utxo')

        if not rr:
            print('nada')
            continue

        here = 0
        for u in rr:
            here += u['value']

            tt = TxIn(h2b_rev(u['txid']), u['vout'])
            spending.append(tt)
            #print(rr)

            pin = BasicPSBTInput(idx=len(psbt.inputs))
            psbt.inputs.append(pin)

            pubkey = pubkey or calc_pubkey(xpubs, path)

            pin.bip32_paths[pubkey] = str2path(xfp, path)

            # fetch the UTXO for witness signging
            td = explora('tx', u['txid'], 'hex', is_json=False)

            #print(f"txis {u['txid']}:\b{td!r}")
            outpt = Tx.from_hex(td.decode('ascii')).txs_out[u['vout']]

            with BytesIO() as b:
                outpt.stream(b)
                pin.witness_utxo = b.getvalue()

            if redeem:
                pin.redeem_script = redeem

        print('%.8f BTC' % (here / 1E8))
        total += here

        if len(spending) > 15:
            print("Reached practical limit on # of inputs. "
                  "You'll need to repeat this process again later.")
            break

    assert total, "Sorry! Didn't find any UTXO"

    print("Found total: %.8f BTC" % (total / 1E8))

    if payout_address:
        print("Planning to send to: %s" % payout_address)
        dest_scr = BTC.contract.for_address(payout_address)

        txn = Tx(2, spending, [TxOut(total, dest_scr)])
    else:
        print("Output section of PSBT will be empty. Change downstream")
        txn = Tx(2, spending, [])

    fee = tx_fee.recommended_fee_for_tx(txn)

    # placeholder, single output that isn't change
    pout = BasicPSBTOutput(idx=0)
    psbt.outputs.append(pout)

    print("Guestimate fee: %.8f BTC" % (fee / 1E8))

    if txn.txs_out:
        txn.txs_out[0].coin_value -= fee

    # write txn into PSBT
    with BytesIO() as b:
        txn.stream(b)
        psbt.txn = b.getvalue()

    out_psbt.write(psbt.as_bytes())

    print("PSBT to be signed:\n\n\t" + out_psbt.name, end='\n\n')