Ejemplo n.º 1
0
    def test_confirm_input(self):
        FEE = 10000

        # create a fake Spendable
        COIN_VALUE = 100000000
        spendables = [
            Spendable(COIN_VALUE, standard_tx_out_script(BITCOIN_ADDRESSES[0]),
                      FAKE_HASHES[1], 0)
        ]

        tx_1 = create_signed_tx(spendables,
                                BITCOIN_ADDRESSES[1:2],
                                wifs=WIFS[:1])

        spendables = tx_1.tx_outs_as_spendable()

        tx_db = dict((tx.hash(), tx) for tx in [tx_1])

        tx_2 = create_signed_tx(spendables,
                                BITCOIN_ADDRESSES[2:3],
                                wifs=WIFS[:3])
        tx_2.validate_unspents(tx_db)

        tx_2 = create_signed_tx([s.as_dict() for s in spendables],
                                BITCOIN_ADDRESSES[2:3],
                                wifs=WIFS[:3])
        tx_2.validate_unspents(tx_db)

        tx_2 = create_signed_tx([s.as_text() for s in spendables],
                                BITCOIN_ADDRESSES[2:3],
                                wifs=WIFS[:3])
        tx_2.validate_unspents(tx_db)
Ejemplo n.º 2
0
    def test_confirm_input_raises(self):
        # create a fake Spendable
        COIN_VALUE = 100000000
        spendables = [Spendable(COIN_VALUE, script_for_address(BITCOIN_ADDRESSES[0]), FAKE_HASH, 0)]

        tx_1 = create_signed_tx(spendables, BITCOIN_ADDRESSES[1:2], wifs=WIFS[:1])
        spendables = tx_1.tx_outs_as_spendable()
        spendables[0].coin_value += 100

        tx_db = dict((tx.hash(), tx) for tx in [tx_1])
        tx_2 = create_signed_tx(spendables, BITCOIN_ADDRESSES[2:3], wifs=WIFS[:3])

        self.assertRaises(BadSpendableError, tx_2.validate_unspents, tx_db)
Ejemplo n.º 3
0
    def test_confirm_input_raises(self):
        FEE = 10000

        # create a fake Spendable
        COIN_VALUE = 100000000
        spendables = [Spendable(COIN_VALUE, standard_tx_out_script(BITCOIN_ADDRESSES[0]), FAKE_HASHES[1], 0)]

        tx_1 = create_signed_tx(spendables, BITCOIN_ADDRESSES[1:2], wifs=WIFS[:1])
        spendables = tx_1.tx_outs_as_spendable()
        spendables[0].coin_value += 100

        tx_db = dict((tx.hash(), tx) for tx in [tx_1])
        tx_2 = create_signed_tx(spendables, BITCOIN_ADDRESSES[2:3], wifs=WIFS[:3])

        self.assertRaises(BadSpendableError, tx_2.validate_unspents, tx_db)
Ejemplo n.º 4
0
    def test_simple_spend(self):

        FEE = 10000

        # create a fake Spendable
        COIN_VALUE = 100000000
        spendables = [Spendable(COIN_VALUE, standard_tx_out_script(BITCOIN_ADDRESSES[0]), FAKE_HASHES[1], 0)]

        EXPECTED_IDS = [
            "d28bff6c4a8a0f9e7d5b7df0670d07b43c5613d8c9b14e84707b1e2c0154a978",
            "7afbe63b00171b18f806ebd48190ebc1c68cadf286a85489c06ebe43d146489e",
            "2b90c150ba1d080a0816952f5d9c2642d408989cbc4d4c540591c8c9241294bd",
            "17b0b5b22887081595c1a9ad153e903f63bb8682ae59d6082df018dc617e5e67",
            "dff1b34c243becb096ad2a2d6119973067a8137cc8bf95615e742bbf6f0944c1",
            "206bbfbb759a8f91901d86b62390d7587f6097a32994ece7752d143fc8a02cee",
            "7841412716ad35cbc9954e547ba85be89e5ed0b34ed5fb8d7594517318dc10d6",
            "8b7e643bf47db46ada7a75b8498990b111fe20917b5610ca6759b8b0078ccd5e",
            "5756f0a6d5a2bbb93a07f0729d3773aaafd21393ede3ec0e20b0b5219ca45548",
            "32dcbb34965ea72d2caa59eb1e907aa28bac2afea43214c1809f5d8ed360f30e",
        ]

        for count in range(1, 11):
            tx = create_signed_tx(spendables, BITCOIN_ADDRESSES[1:count+1], wifs=WIFS[:1])
            self.assertEqual(tx.bad_signature_count(), 0)
            self.assertEqual(tx.fee(), FEE)
            self.assertEqual(tx.id(), EXPECTED_IDS[count-1])
            for idx in range(1, count+1):
                self.assertEqual(tx.txs_out[idx-1].bitcoin_address(), BITCOIN_ADDRESSES[idx])
            # TODO: add check that s + s < generator for each signature
            for i in range(count):
                extra = (1 if i < ((COIN_VALUE - FEE) % count) else 0)
                self.assertEqual(tx.txs_out[i].coin_value, (COIN_VALUE - FEE)//count + extra)
Ejemplo n.º 5
0
def createTX(payment):

    (content,(addrToSend,amountToSend)) = payment
    
    if content is None:
        pass
        # it should include a reason for the  error....
        # raise an exception

        return None # actually instead of returning it should raise an exception....

    else:

        (utxos,retAddr) = content
        keys            = []
        spendings       = []

        for ((txid,index),amount,key) in utxos:

            keys      += [key.wif()]

            spendings += [ Spendable( amount
                                    , ScriptPayToAddress( key.hash160()).script()
                                    , h2b_rev(txid)
                                    , index
                                    )
                         ]
        print "########################################################################################"
        print ('spendings     :',spendings)
        print ('addr to send  :',addrToSend)
        print ('amountToSend  :',amountToSend)
        print ('retAddr       :',retAddr)
        print ('wif list      :',keys)
        print ('transaction   :',create_signed_tx(spendings,[(addrToSend,amountToSend),retAddr],wifs=keys, fee="standard").as_hex())
        print "########################################################################################"
Ejemplo n.º 6
0
    def send(self, payables, fee, change_address=None):
        """
        Send coins list of payees with a fee and return the remaining coins
        to the change address (defaults to sender address)

        Payables should have their coin value in satoshis
        """
        spendables = self.get_unspents()

        # calculate leftover coins
        total_in = sum([s.coin_value for s in spendables])
        total_out = sum([p.value for p in payables])
        leftover = total_in - (total_out + fee)

        if leftover > 0:
            payables.append(Payable(change_address or self.address, leftover))

        # create a signed transaction
        signed_tx = create_signed_tx(spendables,
                                     payables, [
                                         self.key.wif(),
                                     ],
                                     netcode=self.netcode)

        # broadcast transaction to bitcoin network
        for network_api in self.network_apis:
            try:
                return network_api.send(signed_tx)
            except NetworkAPIError:
                continue
        raise NetworkAPIError("All network calls for this method failed!")
Ejemplo n.º 7
0
    def test_simple_spend(self):

        FEE = 10000

        # create a fake Spendable
        COIN_VALUE = 100000000
        spendables = [Spendable(COIN_VALUE, standard_tx_out_script(BITCOIN_ADDRESSES[0]), FAKE_HASHES[1], 0)]

        EXPECTED_IDS = [
            "d28bff6c4a8a0f9e7d5b7df0670d07b43c5613d8c9b14e84707b1e2c0154a978",
            "7afbe63b00171b18f806ebd48190ebc1c68cadf286a85489c06ebe43d146489e",
            "2b90c150ba1d080a0816952f5d9c2642d408989cbc4d4c540591c8c9241294bd",
            "17b0b5b22887081595c1a9ad153e903f63bb8682ae59d6082df018dc617e5e67",
            "dff1b34c243becb096ad2a2d6119973067a8137cc8bf95615e742bbf6f0944c1",
            "206bbfbb759a8f91901d86b62390d7587f6097a32994ece7752d143fc8a02cee",
            "7841412716ad35cbc9954e547ba85be89e5ed0b34ed5fb8d7594517318dc10d6",
            "8b7e643bf47db46ada7a75b8498990b111fe20917b5610ca6759b8b0078ccd5e",
            "5756f0a6d5a2bbb93a07f0729d3773aaafd21393ede3ec0e20b0b5219ca45548",
            "32dcbb34965ea72d2caa59eb1e907aa28bac2afea43214c1809f5d8ed360f30e",
        ]

        for count in range(1, 11):
            tx = create_signed_tx(spendables, BITCOIN_ADDRESSES[1:count+1], wifs=WIFS[:1])
            self.assertEqual(tx.bad_signature_count(), 0)
            self.assertEqual(tx.fee(), FEE)
            self.assertEqual(tx.id(), EXPECTED_IDS[count-1])
            # TODO: add check that s + s < generator for each signature
            for i in range(count):
                extra = (1 if i < ((COIN_VALUE - FEE) % count) else 0)
                self.assertEqual(tx.txs_out[i].coin_value, (COIN_VALUE - FEE)//count + extra)
Ejemplo n.º 8
0
def createTX(payment):

    (content, (addrToSend, amountToSend)) = payment

    if content is None:
        pass
        # it should include a reason for the  error....
        # raise an exception

        return None  # actually instead of returning it should raise an exception....

    else:

        (utxos, retAddr) = content
        keys = []
        spendings = []

        for ((txid, index), amount, key) in utxos:

            keys += [key.wif()]

            spendings += [Spendable(amount, ScriptPayToAddress(key.hash160()).script(), h2b_rev(txid), index)]
        print "########################################################################################"
        print ("spendings     :", spendings)
        print ("addr to send  :", addrToSend)
        print ("amountToSend  :", amountToSend)
        print ("retAddr       :", retAddr)
        print ("wif list      :", keys)
        print (
            "transaction   :",
            create_signed_tx(spendings, [(addrToSend, amountToSend), retAddr], wifs=keys, fee="standard").as_hex(),
        )
        print "########################################################################################"
Ejemplo n.º 9
0
    def test_confirm_input(self):
        FEE = 10000

        # create a fake Spendable
        COIN_VALUE = 100000000
        spendables = [Spendable(COIN_VALUE, standard_tx_out_script(BITCOIN_ADDRESSES[0]), FAKE_HASHES[1], 0)]

        tx_1 = create_signed_tx(spendables, BITCOIN_ADDRESSES[1:2], wifs=WIFS[:1])

        spendables = tx_1.tx_outs_as_spendable()

        tx_db = dict((tx.hash(), tx) for tx in [tx_1])

        tx_2 = create_signed_tx(spendables, BITCOIN_ADDRESSES[2:3], wifs=WIFS[:3])
        tx_2.validate_unspents(tx_db)

        tx_2 = create_signed_tx([s.as_dict() for s in spendables], BITCOIN_ADDRESSES[2:3], wifs=WIFS[:3])
        tx_2.validate_unspents(tx_db)

        tx_2 = create_signed_tx([s.as_text() for s in spendables], BITCOIN_ADDRESSES[2:3], wifs=WIFS[:3])
        tx_2.validate_unspents(tx_db)
Ejemplo n.º 10
0
def processSendBitcoin(fromPrivateKey, toPublicKey, amountOfBitcoin):
	bcip = BlockchainInfoProvider("BTC")
	amountOfSatoshi = int(amountOfBitcoin * 100000000)
	spendables = spendables_for_address(wif2address(fromPrivateKey), "BTC")
	try:
		tx = create_signed_tx(spendables, [(toPublicKey, amountOfSatoshi), wif2address(fromPrivateKey)], [fromPrivateKey], tx_fee.TX_FEE_PER_THOUSAND_BYTES)
	except Exception as e:
		print "could not build transaction."
		print e
		return False
	try:
		bcip.broadcast_tx(tx)
		print "tx broadcasted: ", tx.id()
		return tx.id()
	except:
		print "tx failed to be broadcasted"
		return False
Ejemplo n.º 11
0
    def createTx(self):

        # address = self.fromaddress.text()
        # destination = self.sendto.text()

        address = "mti8znMQPkP9LnPcce7i3LQRuSGZ38PVPV"
        destination = "ms4cSWpPGb6tBzbBXNuBwsarg1SNYvkjxg"

        #あらかじめ送信元アドレスに対応する秘密鍵を入力しておく
        wif = "cNJm4inEA9xreDHntBB9gAFj8V6aSn9sqdVgDdJJGrN9Ys8b8vzD"
        sndtx = BlockchainInfoProvider('blockr.io')

        print("before")
        assert is_valid_wif(wif)
        print("after")

        spendables = spendables_for_address(address, "BTC")
        tx = create_signed_tx(spendables, payables=[destination], wifs=[wif])
        sndtx.broadcast_tx(tx)
        self.transaction.setText(tx.as_hex())
Ejemplo n.º 12
0
    def _make_tx(self, input_script, other_scripts=[]):
        from pycoin.tx.tx_utils import create_signed_tx
        from pycoin.solve.utils import build_p2sh_lookup

        cv = int(50 * 1e8)

        key = self._key
        sec = key.sec()
        wif = key.wif()
        address = key.address()
        p2sh_lookup = build_p2sh_lookup(other_scripts)

        coinbase_tx = Tx.coinbase_tx(public_key_sec=sec, coin_value=cv)
        coinbase_tx.txs_out[0].script = input_script
        spendable = coinbase_tx.tx_outs_as_spendable()[0]
        payables = [(address, cv)]
        tx = create_signed_tx(spendables=[spendable],
                              payables=payables,
                              wifs=[wif],
                              p2sh_lookup=p2sh_lookup)
        tx.unspents = [spendable]
        print(tx.as_hex(include_unspents=True))
        return tx
Ejemplo n.º 13
0
    while 1:
        print("enter the %s => " % which, end='')
        netcode = input()
        if netcode:
            print(netcode)
            return netcode
        print("invalid netcode, please try again")


src_address = get_address("source")
netcode = get_net_code("netcode")
spendables = spendables_for_address(src_address, netcode)
print(spendables)
while 1:
    print("enter the WIF for %s=> " % src_address, end='')
    wif = input()
    is_valid = is_wif_valid(wif)
    if is_valid:
        break
    print("invalid wif, please try again")

key = Key.from_text(wif)
if src_address not in (key.address(use_uncompressed=False),
                       key.address(use_uncompressed=True)):
    print("** WIF doesn't correspond to %s" % src_address)

print("The secret exponent is %d" % key.secret_exponent())
dst_address = get_address("destination")
tx = create_signed_tx(spendables, payables=[dst_address], wifs=[wif])
print("here is the signed output transaction")
print(tx.as_hex())
Ejemplo n.º 14
0
    def test_sign(self, keynums_satoshi, out_addr, out_satoshi, change_keynum,
                  change_satoshi, prevtx_keynums, prevtx_outputs,
                  prevtx_inputs):
        """
        Performs a tx signing test, comparing Polly's signed tx against the reference wallet.
    
        Basic tx signing parameters:
        
        keynums_satoshi - list of tuples (keynum, satoshis) with key indices and their unspent value to 
                          use as tx inputs. Funding above out_satoshi + change_satoshi will be fees.
        out_addr        - output address in bitcoin address format. 
        out_satoshi     - output amount in satoshis.
        change_keynum   - change key index in the wallet, use None for no change.
        change_satoshi  - change amount in satoshis, use 0 for no change. 
        
        
        Supporting (previous) txs will be created to fund keynums and are controlled by these parameters:
        
        prevtx_keynums  - keynums will show up as outputs of previous txs. A number randomly picked 
                          from this list controls how many keynums are chosen to include per prev tx.
        prevtx_outputs  - in addition to previous tx outputs funding keynums, other outputs may 
                          be present. A number randomly picked from this list controls how many 
                          ignored outputs are injected per keynum. 
        prevtx_inputs   - previous txs need inputs too. A number randomly picked from this list 
                          controls how many inputs are chosen per previous tx.
        """

        total_in_satoshi = sum(satoshi for _, satoshi in keynums_satoshi)
        fee_satoshi = total_in_satoshi - out_satoshi - change_satoshi
        chain0 = self.wallet.subkey(0, is_hardened=True).subkey(0)
        chain1 = self.wallet.subkey(0, is_hardened=True).subkey(1)

        assert total_in_satoshi >= out_satoshi + change_satoshi
        assert len(keynums_satoshi) <= 32

        #
        # Step 1: send the inputs and outputs to use in the signed tx
        #

        # Create the (key num, compressed public key) tuple, input keys assume an m/0h/0/keynum path for now.
        keys = [
            (keynum,
             encoding.public_pair_to_sec(chain0.subkey(keynum).public_pair))
            for (keynum, _) in keynums_satoshi
        ]

        # Convert base58 address to raw hex address
        out_addr_160 = encoding.bitcoin_address_to_hash160_sec(out_addr)

        print()
        print("Sign tx parameters:", "")
        for i, (keynum, satoshi) in enumerate(keynums_satoshi):
            print("{:<10}{:16.8f} btc < key {}".format(
                " inputs" if 0 == i else "", satoshi / 100000000, keynum))
        print("{:<10}{:16.8f} btc > {}".format(" output",
                                               out_satoshi / 100000000,
                                               self.hexstr(out_addr_160)))
        print("{:<10}{:16.8f} btc > key {}".format(" change",
                                                   change_satoshi / 100000000,
                                                   change_keynum))
        print("{:<10}{:16.8f} btc".format(" fee", fee_satoshi / 100000000))
        print("{:<10}{:16.8f} btc".format(" total",
                                          total_in_satoshi / 100000000))

        print()
        print(self.PAD.format("Send tx parameters"), end='')

        # ---> send to Polly
        self.polly.send_sign_tx(keys, out_addr_160, out_satoshi, change_keynum,
                                change_satoshi)

        print(self.__outok())

        #
        # Step 2: send previous txs to fund the inputs
        #

        print()

        cur = 0
        prevtx_info = []

        while cur < len(keynums_satoshi):

            prevtx_outputs_satoshi = []

            # Calculate how many keynums will be associated with this prev tx
            end = min(cur + random.choice(prevtx_keynums),
                      len(keynums_satoshi))

            # Create the prev tx output list
            for keynum, satoshi in keynums_satoshi[cur:end]:

                # Inject a random number of outputs not associated with tx input keynums
                for _ in range(0, random.choice(prevtx_outputs)):
                    prevtx_outputs_satoshi.append(
                        (random.randint(0, 0x7FFFFFFF),
                         random.randint(0, 2099999997690000)))

                # Add the outputs funding the tx input keynums
                prevtx_outputs_satoshi.append((keynum, satoshi))

                # Create output script
                addr = chain0.subkey(keynum, as_private=True).bitcoin_address()
                script = standard_tx_out_script(addr)

                # Capture some info we'll use later to verify the signed tx
                prevtx_info.append((
                    keynum,
                    satoshi,
                    script,
                    0,  # This is the hash and will be replaced later
                    len(prevtx_outputs_satoshi) -
                    1))  # Index of the valid output

            print("{:30}{}".format(
                "Make prev tx for keys", " ".join(
                    str(keynum)
                    for (keynum, _, _, _, _) in prevtx_info[cur:])))

            # Create the prev tx
            prevtx = self.create_prev_tx(
                win=Wallet.from_master_secret(
                    bytes(0)),  # create a dummy wallet 
                in_keynum=list(range(0, random.choice(prevtx_inputs))),
                sources_per_input=1,
                wout=chain0,
                out_keynum_satoshi=prevtx_outputs_satoshi,
                fees_satoshi=random.randint(100, 1000))

            # We have built the prev tx, calculate its hash (and reverse the bytes)
            prevtx_hash = encoding.double_sha256(prevtx)[::-1]

            # Update the hashes now that we have a full prev tx
            for i, (keynum, satoshi, script, _,
                    outidx) in enumerate(prevtx_info[cur:]):
                prevtx_info[i + cur] = (keynum, satoshi, script, prevtx_hash,
                                        outidx)

            # Create the index table that matches a keynum index with an ouput index in this prev tx
            idx_table = [
                (keynum_idx + cur, outidx)
                for keynum_idx, (_, _, _, _,
                                 outidx) in enumerate(prevtx_info[cur:])
            ]

            print(self.PAD.format("Send prev tx "), end='')

            # ---> send to Polly
            self.polly.send_prev_tx(idx_table, prevtx)

            print(self.__outok())

            cur = end

        #
        # Step 3: generate a signed tx with the reference wallet and compare against Polly's
        #

        spendables = []
        wifs = []

        # Make sure that the inputs add up correctly, and prep the input_sources for reference wallet signing
        for (keynum, satoshi, script, prevtx_hash, outidx) in prevtx_info:
            spendables.append(Spendable(satoshi, script, prevtx_hash, outidx))
            wifs.append(chain0.subkey(keynum, as_private=True).wif())

        change_addr = chain1.subkey(change_keynum).bitcoin_address()

        payables = [(out_addr, out_satoshi), (change_addr, change_satoshi)]

        print()
        print(self.PAD.format("Make reference signature"))

        signed_tx = create_signed_tx(spendables, payables, wifs, fee_satoshi)
        signed_tx = self.get_tx_bytes(signed_tx)

        print(self.PAD.format("Get signed tx"), end='', flush=True)

        # <--- get the signed tx from Polly
        polly_signed_tx = self.polly.send_get_signed_tx()

        #print(self.txstr(polly_signed_tx))
        #print(self.txstr(signed_tx))

        print(self.__outok())

        # Compare reference wallet signed tx with polly's
        assert signed_tx == polly_signed_tx, "test_sign: signature mismatch\nExpected:\n" + self.hexstr(
            signed_tx) + "\n\nActual:\n" + self.hexstr(polly_signed_tx)
Ejemplo n.º 15
0
		print "enter the %s address=>"%which,
		address=input();
		is_valid=is_address_valid(address)
		if is_valid:
			return address
		print 'invalid address, please try again'

src_address=get_address("source")
spendables=spendables_for_address(src_address)
print spendables

while 1:
	print "enter the WIF for %s" %src_address,
	wif=input()
	is_valid=is_wif_valid(wif)
	if is_valid:
		break
	print("invalid wif, please try again")

key = key.from_text(wif)
if src_address not in (key.address(use_uncompressed=False), key.address(use_uncompressed=True)):
	print("**WIF doesn't correspond to %s" %src_address)
print("The secret exponent is %d"%key.secret_exponent())

dst_address=get_address("destination")

tx=create_signed_tx(spendables, payables=[dst_address], wifs=[wif])

print 'here is the signed output transaction'
print(tx.as_hex())
Ejemplo n.º 16
0
    utxos = json.loads(urlopen(URL).read().decode("utf8"))

    utxo = utxos[0]

    return Spendable(utxo['amount'], h2b(utxo.get("scriptPubKey")),
                     h2b_rev(utxo.get("txid")), utxo.get("vout"))


amount, script_hex = get_spendable(from_address)

spendable = Spendable(amount, script_hex)
##################
# TODO: 设计amount计算
tx = create_signed_tx([spendable],
                      [(to_address, btc_to_satoshi("0.00005")),
                       (btc_withdraw_address, btc_to_satoshi("0.0015"))],
                      fee=btc_to_satoshi("0.00005"),
                      wifs=[master_key.wif()],
                      netcode=args.netcode)

tx_as_hex = tx.as_hex()
print tx_as_hex
# TODO 节点选取
# url = "https://test-insight.bitpay.com/api/tx/send"
# data = urlencode(dict(rawtx=tx_as_hex)).encode("utf8")

# AGENT = 'pycoin/%s' % version
#req = request.Request(url, data=data)
#r = request.urlopen(req).read()
#print r
Ejemplo n.º 17
0
def process(request):
    if request.method == 'POST':
        # auto deposit function
        if request.POST.get('VERY_LONG_RANDOM_STRING'):
            account_record = AccountModel.objects.create(
                return_address=chikun_address)
            account_record.save()
            deposit_address = master_public_key.subkey(
                account_record.id).address()
            return HttpResponse(deposit_address)

        response = system('ping -c 1 -w 3 %s > /dev/null 2>&1' % hostname)
        if request.POST.get('v_key') == v_key and response == 0:
            # check balance stats for all balance 0's
            zero_list = AccountModel.objects.filter(balance=0)
            if zero_list.exists():

                for i in zero_list:
                    address = master_public_key.subkey(i.id).address()

                    try:
                        balance = Decimal(
                            urlopen(
                                'https://%s/q/addressbalance/%s?confirmations=%s&api_code=%s'
                                % (hostname, address, confirmations,
                                   api_code)).read()) / 100000000  # REMOTE
                    except Exception as e:
                        lf = open('logFile', 'a')
                        print('try one: ', end='')
                        print(e, file=lf)
                        lf.close()
                        return HttpResponse(status=204)

                    if balance >= Decimal('0.001'):
                        i.balance = balance

                    i.checked += 1
                    i.save()

# match valid accounts and make payments
            nonzero_list = AccountModel.objects.filter(
                balance__gt=0).order_by('?')
            if len(nonzero_list) > 1:
                v = True
                limit = len(nonzero_list) / 2 if not len(
                    nonzero_list) % 2 else (len(nonzero_list) - 1) / 2
                nonzero_list = nonzero_list[:limit * 2]

            else:
                v = False
            if v:
                slice_one = nonzero_list[:limit]
                slice_two = nonzero_list[limit:]

                c = 0
                while c < limit:
                    if not slice_one[c].balance == slice_two[c].balance:
                        (winner, loser) = (
                            slice_one[c], slice_two[c]
                        ) if slice_one[c].balance > slice_two[c].balance else (
                            slice_two[c], slice_one[c])

                        winner_key = Key.from_text(
                            request.POST['private_key']).subkey(winner.id)
                        loser_key = Key.from_text(
                            request.POST['private_key']).subkey(loser.id)

                        try:
                            spendables = spendables_for_address(
                                '%s&api_code=%s' %
                                (winner_key.address(),
                                 api_code)) + spendables_for_address(
                                     '%s&api_code=%s' %
                                     (loser_key.address(), api_code))
                            signed_tx = create_signed_tx(
                                spendables,
                                [(chikun_address,
                                  int((loser.balance * vig) * 100000000)),
                                 winner.return_address],
                                wifs=[winner_key.wif(),
                                      loser_key.wif()],
                                fee="standard")

                            pushtx(signed_tx.as_hex())

                            ResultModel.objects.create(
                                winning_address=winner_key.address(),
                                winning_deposit=str(winner.balance),
                                losing_address=loser_key.address(),
                                losing_deposit=str(loser.balance),
                                txid=signed_tx.id()).save()

                            for i in (winner, loser):
                                ArchiveModel.objects.create(
                                    **AccountModel.objects.filter(
                                        id=i.id).values()[0]).save()
                                AccountModel.objects.filter(id=i.id).delete()

                        except Exception as e:
                            lf = open('logFile', 'a')
                            print('try two: ', end='')
                            print(e, file=lf)
                            lf.close()
                            for i in (winner, loser):
                                BrokenModel.objects.create(
                                    **AccountModel.objects.filter(
                                        id=i.id).values()[0]).save()
                                AccountModel.objects.filter(id=i.id).delete()

                    c += 1

# remove invalid accounts
            invalid_accounts = AccountModel.objects.filter(
                checked__gt=24).filter(balance=0)  # four hours
            if invalid_accounts.exists():

                for i in invalid_accounts:
                    InvalidModel.objects.create(**AccountModel.objects.filter(
                        id=i.id).values()[0]).save()
                    AccountModel.objects.filter(id=i.id).delete()

            return HttpResponse(status=204)

    return HttpResponse(
        '<h1>Not Found</h1><p>The requested URL /with was not found on this server.</p>',
        status=404)
Ejemplo n.º 18
0
    def test_sign(self, keynums_satoshi, out_addr, out_satoshi, change_keynum, change_satoshi, prevtx_keynums, prevtx_outputs, prevtx_inputs):
        """
        Performs a tx signing test, comparing Polly's signed tx against the reference wallet.
    
        Basic tx signing parameters:
        
        keynums_satoshi - list of tuples (keynum, satoshis) with key indices and their unspent value to 
                          use as tx inputs. Funding above out_satoshi + change_satoshi will be fees.
        out_addr        - output address in bitcoin address format. 
        out_satoshi     - output amount in satoshis.
        change_keynum   - change key index in the wallet, use None for no change.
        change_satoshi  - change amount in satoshis, use 0 for no change. 
        
        
        Supporting (previous) txs will be created to fund keynums and are controlled by these parameters:
        
        prevtx_keynums  - keynums will show up as outputs of previous txs. A number randomly picked 
                          from this list controls how many keynums are chosen to include per prev tx.
        prevtx_outputs  - in addition to previous tx outputs funding keynums, other outputs may 
                          be present. A number randomly picked from this list controls how many 
                          ignored outputs are injected per keynum. 
        prevtx_inputs   - previous txs need inputs too. A number randomly picked from this list 
                          controls how many inputs are chosen per previous tx.
        """
        
        total_in_satoshi = sum(satoshi for _, satoshi in keynums_satoshi) 
        fee_satoshi      = total_in_satoshi - out_satoshi - change_satoshi
        chain0           = self.wallet.subkey(0, is_hardened = True).subkey(0)
        chain1           = self.wallet.subkey(0, is_hardened = True).subkey(1)
        
        assert total_in_satoshi >= out_satoshi + change_satoshi
        assert len(keynums_satoshi) <= 32
    
        #
        # Step 1: send the inputs and outputs to use in the signed tx
        #
        
        # Create the (key num, compressed public key) tuple, input keys assume an m/0h/0/keynum path for now. 
        keys = [(keynum, encoding.public_pair_to_sec(chain0.subkey(keynum).public_pair)) 
                for (keynum, _) in keynums_satoshi] 
        
        # Convert base58 address to raw hex address
        out_addr_160 = encoding.bitcoin_address_to_hash160_sec(out_addr)
        
        print()
        print("Sign tx parameters:", "")
        for i, (keynum, satoshi) in enumerate(keynums_satoshi):
            print("{:<10}{:16.8f} btc < key {}".format (" inputs" if 0 == i else "", satoshi          / 100000000, keynum))
        print("{:<10}{:16.8f} btc > {}".format         (" output",                   out_satoshi      / 100000000, self.hexstr(out_addr_160)))
        print("{:<10}{:16.8f} btc > key {}".format     (" change",                   change_satoshi   / 100000000, change_keynum))
        print("{:<10}{:16.8f} btc".format              (" fee",                      fee_satoshi      / 100000000))
        print("{:<10}{:16.8f} btc".format              (" total",                    total_in_satoshi / 100000000))
       
        print()
        print(self.PAD.format("Send tx parameters"), end='')
        
        # ---> send to Polly 
        self.polly.send_sign_tx(keys, out_addr_160, out_satoshi, change_keynum, change_satoshi) 

        print(self.__outok())
    
        #
        # Step 2: send previous txs to fund the inputs
        #
    
        print()

        cur = 0
        prevtx_info = []
    
        while cur < len(keynums_satoshi) :
    
            prevtx_outputs_satoshi = []
            
            # Calculate how many keynums will be associated with this prev tx
            end = min(cur + random.choice(prevtx_keynums), len(keynums_satoshi))
            
            # Create the prev tx output list
            for keynum, satoshi in keynums_satoshi[cur:end] :
        
                # Inject a random number of outputs not associated with tx input keynums
                for _ in range(0, random.choice(prevtx_outputs)) :
                    prevtx_outputs_satoshi.append((random.randint(0, 0x7FFFFFFF),  
                                                    random.randint(0, 2099999997690000)))
    
                # Add the outputs funding the tx input keynums 
                prevtx_outputs_satoshi.append((keynum, satoshi))
    
                # Create output script
                addr   = chain0.subkey(keynum, as_private = True).bitcoin_address()
                script = standard_tx_out_script(addr)
    
                # Capture some info we'll use later to verify the signed tx
                prevtx_info.append((keynum, 
                                    satoshi,
                                    script,
                                    0,                                # This is the hash and will be replaced later
                                    len(prevtx_outputs_satoshi) - 1)) # Index of the valid output
                
            print("{:30}{}".format("Make prev tx for keys", " ".join(str(keynum) for (keynum, _, _, _, _) in prevtx_info[cur:])))
            
            # Create the prev tx
            prevtx = self.create_prev_tx(win                 = Wallet.from_master_secret(bytes(0)), # create a dummy wallet 
                                         in_keynum           = list(range(0, random.choice(prevtx_inputs))), 
                                         sources_per_input   = 1, 
                                         wout                = chain0, 
                                         out_keynum_satoshi  = prevtx_outputs_satoshi, 
                                         fees_satoshi        = random.randint(100, 1000))
            
            # We have built the prev tx, calculate its hash (and reverse the bytes) 
            prevtx_hash = encoding.double_sha256(prevtx)[::-1] 
    
            # Update the hashes now that we have a full prev tx
            for i, (keynum, satoshi, script, _, outidx) in enumerate(prevtx_info[cur:]) :
                prevtx_info[i + cur] = (keynum, satoshi, script, prevtx_hash, outidx)
                
            # Create the index table that matches a keynum index with an ouput index in this prev tx
            idx_table = [(keynum_idx + cur, outidx) for keynum_idx, (_, _, _, _, outidx) in enumerate(prevtx_info[cur:])] 
            
            print(self.PAD.format("Send prev tx "), end='')
            
            # ---> send to Polly
            self.polly.send_prev_tx(idx_table, prevtx)
    
            print(self.__outok())
    
            cur = end
        
        #
        # Step 3: generate a signed tx with the reference wallet and compare against Polly's
        #
    
        spendables = []
        wifs       = []
        
        # Make sure that the inputs add up correctly, and prep the input_sources for reference wallet signing
        for (keynum, satoshi, script, prevtx_hash, outidx) in prevtx_info:
            spendables.append(Spendable(satoshi, script, prevtx_hash, outidx))
            wifs.append(chain0.subkey(keynum, as_private = True).wif())
        
        change_addr = chain1.subkey(change_keynum).bitcoin_address()
        
        payables = [(out_addr, out_satoshi), (change_addr, change_satoshi)]
        
        print()
        print(self.PAD.format("Make reference signature"))
    
        signed_tx     = create_signed_tx(spendables, payables, wifs, fee_satoshi)
        signed_tx     = self.get_tx_bytes(signed_tx)
        
        print(self.PAD.format("Get signed tx"), end='', flush = True)
        
        # <--- get the signed tx from Polly
        polly_signed_tx = self.polly.send_get_signed_tx()

        #print(self.txstr(polly_signed_tx))
        #print(self.txstr(signed_tx))
        
        print(self.__outok())
        
        # Compare reference wallet signed tx with polly's 
        assert signed_tx == polly_signed_tx, "test_sign: signature mismatch\nExpected:\n" + self.hexstr(signed_tx) + "\n\nActual:\n" + self.hexstr(polly_signed_tx)
Ejemplo n.º 19
0
def process(request):
    if request.method == 'POST':
# auto deposit function
        if request.POST.get('VERY_LONG_RANDOM_STRING'):
            account_record = AccountModel.objects.create(return_address=chikun_address)
            account_record.save()
            deposit_address = master_public_key.subkey(account_record.id).address()
            return HttpResponse(deposit_address)

        response = system('ping -c 1 -w 3 %s > /dev/null 2>&1' % hostname)
        if request.POST.get('v_key') == v_key and response == 0:
# check balance stats for all balance 0's
            zero_list = AccountModel.objects.filter(balance=0)
            if zero_list.exists():

                for i in zero_list:
                    address = master_public_key.subkey(i.id).address()

                    try:
                        balance = Decimal(urlopen('https://%s/q/addressbalance/%s?confirmations=%s&api_code=%s' % (hostname, address, confirmations, api_code)).read()) / 100000000  # REMOTE
                    except Exception as e:
                        lf = open('logFile', 'a')
                        print('try one: ', end='')
                        print(e, file=lf)
                        lf.close()
                        return HttpResponse(status=204)

                    if balance >= Decimal('0.001'):
                        i.balance = balance

                    i.checked += 1
                    i.save()

# match valid accounts and make payments
            nonzero_list = AccountModel.objects.filter(balance__gt=0).order_by('?')
            if len(nonzero_list) > 1:
                v = True
                limit = len(nonzero_list) / 2 if not len(nonzero_list) % 2 else (len(nonzero_list) - 1) / 2
                nonzero_list = nonzero_list[:limit * 2]

            else:
                v = False
            if v:
                slice_one = nonzero_list[:limit]
                slice_two = nonzero_list[limit:]

                c = 0
                while c < limit:
                    if not slice_one[c].balance == slice_two[c].balance:
                        (winner, loser) = (slice_one[c], slice_two[c]) if slice_one[c].balance > slice_two[c].balance else (slice_two[c], slice_one[c])

                        winner_key = Key.from_text(request.POST['private_key']).subkey(winner.id)
                        loser_key = Key.from_text(request.POST['private_key']).subkey(loser.id)

                        try:
                            spendables = spendables_for_address('%s&api_code=%s' % (winner_key.address(), api_code)) + spendables_for_address('%s&api_code=%s' % (loser_key.address(), api_code))
                            signed_tx = create_signed_tx(spendables,
                                                         [(chikun_address, int((loser.balance * vig) * 100000000)), winner.return_address],
                                                         wifs=[winner_key.wif(), loser_key.wif()], fee="standard")

                            pushtx(signed_tx.as_hex())

                            ResultModel.objects.create(winning_address=winner_key.address(), winning_deposit=str(winner.balance),
                                                       losing_address=loser_key.address(), losing_deposit=str(loser.balance),
                                                       txid=signed_tx.id()).save()

                            for i in (winner, loser):
                                ArchiveModel.objects.create(**AccountModel.objects.filter(id=i.id).values()[0]).save()
                                AccountModel.objects.filter(id=i.id).delete()

                        except Exception as e:
                            lf = open('logFile', 'a')
                            print('try two: ', end='')
                            print(e, file=lf)
                            lf.close()
                            for i in (winner, loser):
                                BrokenModel.objects.create(**AccountModel.objects.filter(id=i.id).values()[0]).save()
                                AccountModel.objects.filter(id=i.id).delete()

                    c += 1

# remove invalid accounts
            invalid_accounts = AccountModel.objects.filter(checked__gt=24).filter(balance=0)  # four hours
            if invalid_accounts.exists():

                for i in invalid_accounts:
                    InvalidModel.objects.create(**AccountModel.objects.filter(id=i.id).values()[0]).save()
                    AccountModel.objects.filter(id=i.id).delete()

            return HttpResponse(status=204)

    return HttpResponse('<h1>Not Found</h1><p>The requested URL /with was not found on this server.</p>', status=404)