Esempio n. 1
0
#!/usr/bin/env python

import codecs
from bitcoin.rpc import Proxy

if __name__ == '__main__':
    url = raw_input('Please enter the RPC url: ')
    username = raw_input('Please enter the RPC username: '******'Please enter the RPC password: '******'out.csv', 'w', 'utf-8')

    for idx in xrange(numblocks):
        blockinfo = proxy.getblock(proxy.getblockhash(idx))
        fp.write(','.join(
            map(str, [
                blockinfo['height'],
                blockinfo['time'],
                blockinfo['difficulty'],
            ])) + '\n')

    fp.close()
Esempio n. 2
0
    def _sync_block(self):
        p = Proxy()
        blockcount = p.getblockcount()
        print("sync blockcount = " + str(blockcount))

        with closing(sqlite3.connect(self.dbname)) as connection:
            cursor = connection.cursor()

            checkedcount = self._get_checked_count(cursor)
            print("sync checkedcount = " + str(checkedcount))

            if checkedcount < CHECKPOINT:
                checkedcount = CHECKPOINT

            lastblock = blockcount - CONFIRMATIONS
            if lastblock <= 0:
                return

            for i in range(checkedcount + 1, blockcount - CONFIRMATIONS):
                if self.stopped:
                    break

                print("sync blockheight = " + str(i))
                block = p.getblockbynumber(i)
                if block is None:
                    continue
                if BLOCK_KEY_TX not in block.keys():
                    continue

                for transactionid in block[BLOCK_KEY_TX]:
                    transaction = p.gettransaction(transactionid)

                    if transaction is None:
                        continue

                    if TRANSACTION_KEY_AMOUNT not in transaction.keys():
                        continue

                    amount = transaction[TRANSACTION_KEY_AMOUNT]
                    if amount <= 0:
                        print("sync amount div")
                        continue
                    amount = CWalletSyncher._str_round_down8(amount)
                    print("sync amount = " + amount)

                    if TRANSACTION_KEY_DETAILS not in transaction.keys():
                        print("sync dont have details!!")
                        continue

                    print("sync found receive!!")
                    details = transaction[TRANSACTION_KEY_DETAILS]
                    for detail in details:
                        category = detail[TRANSACTION_KEY_CATEGORY]
                        if (category != TRANSACTION_VALUE_CATEGORY_RECEIVE):
                            continue

                        address = detail[TRANSACTION_KEY_ADDRESS]

                        print("sync receive address = " + address)
                        with self.dblock:
                            row = self.dbaccessor.get_user_by_address(
                                cursor, address)
                            if row is not None:
                                height = row[
                                    walletdb.WalletNum.LASTSYNCBLOCK.value]
                                print("sync receive username = "******" balance = " +
                                      row[walletdb.WalletNum.BALANCE.value] +
                                      " height = " +
                                      str(row[walletdb.WalletNum.LASTSYNCBLOCK.
                                              value]))

                                src_balance = CWalletSyncher._round_down8(
                                    str(row[walletdb.WalletNum.BALANCE.value]))
                                dst_balance = src_balance + \
                                    CWalletSyncher._round_down8(amount)
                                if dst_balance < CWalletSyncher._round_down8(
                                        "0.0"):
                                    dst_balance = CWalletSyncher._round_down8(
                                        "0.0")
                                print("sync update balance = " +
                                      str(dst_balance) + " amount = " + amount)
                                if not self.dbaccessor.update_balance_with_blockheight(
                                        cursor,
                                        row[walletdb.WalletNum.ID.value],
                                        dst_balance, i):
                                    print("sync update faild.")
                                    return
                                self.logger.debug(
                                    "username="******" before=" +
                                    CWalletSyncher._str_round_down8(
                                        src_balance) + " after=" +
                                    CWalletSyncher._str_round_down8(
                                        dst_balance) + " height=" + str(i))
                        break
                    pass
                self._update_checked_count(cursor, i)
                connection.commit()
Esempio n. 3
0
class TX(object):
    def __init__(self, logger=None, test=False):
        self.logger = logger or logging.getLogger(__name__)

        # Setup logging file handler
        self.logger.setLevel(logging.DEBUG)
        self.handler = logging.FileHandler(__name__ + '.log')
        self.handler.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(asctime)s - %(name)s - ' +
                                      '%(levelname)s:\n\t %(message)s')
        self.handler.setFormatter(formatter)

        self.logger.addHandler(self.handler)
        self.test = test
        # if test:
        #     SelectParams('testnet')
        if not test:
            self.proxy = Proxy()

    def __del__(self):
        self.handler.close()

    ###########################################################################
    ## General TX Functions
    ###########################################################################

    def get_tx(self,
               redeem_script,
               address,
               amount,
               funding_tx,
               lock_time=0,
               vout=0):
        '''
               Returns a raw transaction and it's signature hash
               that pays to address from funding_tx

               Options:
               vout -> which vout of funding_tx
               nLockTime -> set's transaction locktime
        '''

        # Set P2SH funding tx in little-endian
        fx = lx(funding_tx)

        if lock_time > 0:
            nlock_time = lock_time
        else:
            nlock_time = 0

        # nSequence must be any number less than 0xffffffff to enable nLockTime
        if (nlock_time != 0):
            txin = CMutableTxIn(COutPoint(fx, vout), nSequence=0)
        else:
            txin = CMutableTxIn(COutPoint(fx, vout))

        # Convert amount to Satoshi's
        amount *= COIN

        # Create the txout to address
        script_pubkey = CBitcoinAddress(address).to_scriptPubKey()
        txout = CMutableTxOut(amount, script_pubkey)

        # Create the unsigned transaction.
        tx = CMutableTransaction([txin], [txout], nLockTime=nlock_time)

        # Calculte TX sig hash
        sighash = SignatureHash(CScript(redeem_script), tx, 0, SIGHASH_ALL)

        self.logger.info("get_tx: TX SIGHASH is %s", b2x(sighash))

        return (tx.serialize(), sighash)

    def refund_tx(self, payer_sig, serial_tx, redeem_script):
        '''
            Sends a transaction refunding the funder of
            the P2SH address.
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Set script sig
        txin.scriptSig = CScript([payer_sig + '\x01', OP_FALSE, redeem_script])

        # Verify script
        redeem_script = CScript(redeem_script)
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("refund_tx: TXID is %s", txid)
        self.logger.info("refund_tx: RAW TX is %s", b2x(serial_tx))

        return serial_tx

    ###########################################################################
    ## Serialization related
    ###########################################################################

    def serialize_list(self, l):
        '''
            Serializes a python list
        '''
        serial = ""
        for i in range(len(l)):
            serial += l[i]
        return serial

    def get_keys_from_tx(self, serial_tx, n_keys=15):
        '''Extracts n_keys from tx in serial form'''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        # Keys are in txin.scriptSig
        txin = tx.vin[0]
        script = txin.scriptSig

        # Extract keys from script
        keys = []
        for i, op in enumerate(script):
            if i in range(1, n_keys + 1):
                keys += [op]

        # Serialize keys in correct order
        serial_keys = ""
        for op in reversed(keys):
            serial_keys += op

        return serial_keys

    def get_keys_from_serial(self, serial, n_keys=15, key_len=16):
        ''' Returns a list of n_keys of key_len extracted from serial'''

        expected = (n_keys * key_len)
        if len(serial) != expected:
            self.logger.error(
                "get_keys_from_serial: serial len is %d " + "expected %d",
                len(serial), expected)
            return []

        keys = []
        for i in range(n_keys):
            keys += [serial[i * key_len:key_len * (i + 1)]]

        return keys

    def get_hashes_from_serial(self, serial, n_hashes, hash_len):
        ''' Returns a list of n_hashes of hash_len extracted from serial'''

        expected = (n_hashes * hash_len)
        if len(serial) != expected:
            self.logger.error(
                "get_hashes_from_serial: serial len is %d " + "expected %d",
                len(serial), expected)
            return []

        hashes = []
        for i in range(n_hashes):
            hashes += [serial[i * hash_len:hash_len * (i + 1)]]

        return hashes

    ###########################################################################
    ## Preimage P2SH wth Refund
    ###########################################################################

    def create_hash_script(self, redeemer_pubkey, hashes):
        '''
            Creates part of the redeem script that deals
            with the hashes
        '''
        script = []
        for h in hashes:
            script += [OP_RIPEMD160, h, OP_EQUALVERIFY]
        script += [redeemer_pubkey, OP_CHECKSIG]
        return script

    def setup_preimage(self, payer_pubkey, redeemer_pubkey, hashes, amount,
                       lock_time):
        '''
            Setups a P2SH that can only be redeemed
            if the redeemer is able to provide
            the hash preimages.
            Also, sends a tx funding the escrow
            (Assumes payer calls the setup)
        '''

        # Set locktime relative to current block
        if not self.test:
            lock = self.proxy.getblockcount() + lock_time
        else:
            lock = lock_time

        script = self.create_hash_script(redeemer_pubkey, hashes)
        redeem_script = CScript([OP_IF] + script + [
            OP_ELSE, lock, OP_CHECKLOCKTIMEVERIFY, OP_DROP, payer_pubkey,
            OP_CHECKSIG, OP_ENDIF
        ])

        redeem = b2x(redeem_script)
        self.logger.info("setup_preimage: Redeem script is %s", redeem)

        # Get P2SH address
        # 1. Get public key
        script_pub_key = redeem_script.to_p2sh_scriptPubKey()

        # 2. Get bitcoin address
        p2sh_address = CBitcoinAddress.from_scriptPubKey(script_pub_key)
        self.logger.info("setup_preimage: P2SH is %s", str(p2sh_address))

        # 3. Fund address
        if not self.test:
            # funding_tx = self.proxy.call("sendtoaddress", str(p2sh_address),
            #                              amount)
            funding_tx = FUNDING_TX
            self.logger.info("setup_preimage: P2SH Fund TX is %s", funding_tx)
        else:
            funding_tx = FUNDING_TX

        return (redeem_script, str(funding_tx), str(p2sh_address), str(lock))

    def spend_preimage(self, preimages, redeemer_sig, serial_tx,
                       redeem_script):
        '''
            Sends a transaction fulfilling the redeem script
            of the preimage P2SH
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Setup preimages in reverse order
        script = []
        for p in reversed(preimages):
            script += [p]

        # Create script sig
        txin.scriptSig = CScript([redeemer_sig + '\x01'] + script +
                                 [OP_TRUE, redeem_script])

        # Verify script
        redeem_script = CScript(redeem_script)
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("spend_preimage: TXID is %s", txid)
        self.logger.info("spend_preimage: RAW TX is %s", b2x(serial_tx))

        return serial_tx

    ###########################################################################
    ## Two Party Escrow with Refund
    ###########################################################################

    def setup_escrow(self, payer_pubkey, redeemer_pubkey, amount, lock_time):
        '''
            Setups a 2of2 escrow with payer and redeemer
            Also, sends a tx funding the escrow
            (Assumes payer calls the setup)
        '''

        # Set locktime relative to current block
        if not self.test:
            lock = self.proxy.getblockcount() + lock_time
            self.logger.info("setup_escrow: Locktime is %d", lock)
        else:
            lock = lock_time

        redeem_script = CScript([
            OP_IF, OP_2, payer_pubkey, redeemer_pubkey, OP_2, OP_CHECKMULTISIG,
            OP_ELSE, lock, OP_CHECKLOCKTIMEVERIFY, OP_DROP, payer_pubkey,
            OP_CHECKSIG, OP_ENDIF
        ])

        redeem = b2x(redeem_script)
        self.logger.info("setup_escrow: Redeem script is %s", redeem)

        # Get P2SH address
        # 1. Get public key
        script_pub_key = redeem_script.to_p2sh_scriptPubKey()

        # 2. Get bitcoin address
        p2sh_address = CBitcoinAddress.from_scriptPubKey(script_pub_key)
        self.logger.info("setup_escrow: P2SH is %s", str(p2sh_address))

        # 3. Fund address
        if not self.test:
            funding_tx = self.proxy.call("sendtoaddress", str(p2sh_address),
                                         amount)
            self.logger.info("setup_escrow: P2SH Fund TX is %s", funding_tx)
        else:
            funding_tx = FUNDING_TX

        return (redeem_script, str(funding_tx), str(p2sh_address), str(lock))

    def spend_escrow(self, payer_sig, redeemer_sig, serial_tx, redeem_script):
        '''
            Sends a transaction fulfilling the redeem script of escrow tx
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Set script sig
        txin.scriptSig = CScript([
            OP_FALSE, payer_sig + '\x01', redeemer_sig + '\x01', OP_TRUE,
            redeem_script
        ])

        # Verify script
        redeem_script = CScript(redeem_script)
        serial_tx = tx.serialize()
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("spend_escrow: TXID is %s", txid)
        self.logger.info("spend_escrow: RAW TX is %s", b2x(serial_tx))

        return serial_tx
#!/usr/bin/env python

import codecs
from bitcoin.rpc import Proxy

if __name__ == '__main__':
    url      = raw_input('Please enter the RPC url: ')
    username = raw_input('Please enter the RPC username: '******'Please enter the RPC password: '******'out.csv', 'w', 'utf-8')

    for idx in xrange(numblocks):
        blockinfo = proxy.getblock(proxy.getblockhash(idx))
        fp.write(','.join(map(str, [
            blockinfo['height'],
            blockinfo['time'],
            blockinfo['difficulty'],
        ]))+'\n')
    
    fp.close()
Esempio n. 5
0
            # else:
            # # print("unknown")
            # self.unknowns.append([txid, b2x(spk)])
            self.type = type
            self.found |= self.type.value
            if self.printed & self.type.value:
                pass
            elif self.type.value:
                self.process(g1, g2, g3, k)
            else:  #unknown type
                self.process('', '', '', k)


if __name__ == "__main__":
    make_addresses()
    latest = proxy.getblockcount()
    i = -1
    txn = Transaction()
    while True:
        i += 1
        j = -1
        if txn.found == 255: break
        bhash = proxy.getblockhash(latest - i)
        block = proxy.getblock(bhash)
        bhash = b2lx(bhash)
        for tx in block.vtx:
            j += 1
            if txn.found == 255: break
            txid = b2lx(tx.GetTxid())
            txn.gettxn(txid)
Esempio n. 6
0
class Blockchain:
    def __init__(self):
        self.proxy = Proxy('http://*****:*****@blockchain.infnote.com:8962')

    @staticmethod
    def deserialize_transaction(raw_tx):
        return CTransaction.deserialize(unhexlify(raw_tx.encode('utf8')))

    def decode_transaction(self, tx):
        contents = []
        for out in tx.vout:
            if out.nValue > 0:
                continue
            data = self.get_data_from_vout(out)
            if data:
                contents.append(data)
        return contents

    def send_transaction(self, raw_tx):
        transaction = self.deserialize_transaction(raw_tx)
        txid = self.proxy.sendrawtransaction(transaction)
        return txid

    @staticmethod
    def get_data_from_vout(vout):
        i = iter(vout.scriptPubKey)
        flag = next(i)
        # TODO: 需要区分类型,以填充至不同的模型
        if flag == script.OP_RETURN or flag == script.OP_NOP8:
            data = next(i).decode('utf8')
            return json.loads(data)
        return None

    def get_transaction(self, txid):
        return self.proxy.getrawtransaction(txid)

    def get_block_count(self):
        return self.proxy.getblockcount()

    def get_block_by_height(self, height: int):
        return self.proxy.getblock(self.proxy.getblockhash(height))

    def server_unspent(self):
        return self.proxy.listunspent()

    @staticmethod
    def freeze_coins_in_tx(tx: CTransaction):
        for vin in tx.vin:
            coin = Coin.objects.get(txid=b2lx(vin.prevout.hash),
                                    vout=vin.prevout.n)
            coin.frozen = True
            coin.save()

    def send_coin_to(self, address, coin: Coin):
        txin = CMutableTxIn(COutPoint(lx(coin.txid), coin.vout))
        txout = CMutableTxOut(coin.value - 1e5,
                              CBitcoinAddress(address).to_scriptPubKey())
        tx = CMutableTransaction([txin], [txout])
        tx = self.proxy.signrawtransaction(tx)['tx']

        # sig_hash = SignatureHash(txin_script_pubkey, tx, 0, SIGHASH_ALL)
        # sig = seckey.sign(sig_hash) + bytes([SIGHASH_ALL])
        # txin.scriptSig = CScript([sig, seckey.pub])
        # VerifyScript(txin.scriptSig, txin_script_pubkey, tx, 0, (SCRIPT_VERIFY_P2SH,))
        # print(b2x(tx.serialize()))

        self.proxy.sendrawtransaction(tx)
        coin.frozen = True
        coin.save()