コード例 #1
0
ファイル: blockchain.py プロジェクト: TAIIOK/memechain-api
def get_op_return_data(txid):
    """
    Method used to get op_return data from transaction

    Args:
            Transaction id (str)

    Returns:
            Embedded metadata (str)
            Author address (str)
    """
    rpc = AuthServiceProxy(
        ("http://%s:%[email protected]:%s/") %
        (config['RPC_USER'], config['RPC_PASS'], config['RPC_PORT']))

    raw_tx = rpc.getrawtransaction(txid)
    tx_data = rpc.decoderawtransaction(raw_tx)

    for data in tx_data["vout"]:
        if data["scriptPubKey"]["asm"][:9] == "OP_RETURN":
            op_return_data = str(unhexlify(data["scriptPubKey"]["asm"][10:]),
                                 encoding='utf-8')
        else:
            op_return_data = None

    try:
        author = tx_data['vout'][0]['scriptPubKey']['addresses'][0]
    except KeyError as e:
        author = None

    return op_return_data, author
コード例 #2
0
def gettxs():
    """Return FLO txid"""
    con = conn()

    access = AuthServiceProxy("http://%s:%[email protected]:%s" %
                              (app.config['CURRENCY_B_RPC_USER'],
                               app.config['CURRENCY_B_RPC_PASSWORD'],
                               app.config['CURRENCY_B_RPC_PORT']))

    # Check for the existing txid
    cur = con.cursor(prepared=True)

    txid = request.form.get("btc_txid")

    cur.execute("SELECT * FROM action WHERE txidreceive = %s;", [txid])
    result = cur.fetchone()

    if not result:
        cur.close()
        con.close()
        return 'nothing-yet'

    rawtx = access.getrawtransaction(str(result[2]))
    txinfo = access.decoderawtransaction(rawtx)

    cur.close()
    con.close()

    return str(result[2]) + "/////" + str(txinfo)
コード例 #3
0
ファイル: btcmirror.py プロジェクト: drxzcl/btcmirror
def main():
    access = ServiceProxy("http://*****:*****@127.0.0.1:8332")
    txid = sys.argv[1]
    # print txid
    txinfo = access.gettransaction(txid)
    pprint.pprint(txinfo)

    # Check the details to make sure it's an incoming transaction
    # Ensure everything is incoming, to avoid 
    # mirroring change/consolidation transactions.    
    myaddresses = set()
    for details in txinfo["details"]:
        # print details
        if details["category"] != "receive":
            return
        myaddresses.add(details["address"])

    tx = access.decoderawtransaction(txinfo["hex"])
    pprint.pprint(tx)
    # Now gather all the outputs to send back
    newtx_inputs = []
    total_amount = Decimal(0)
    for vout in tx["vout"]:
        for address in vout["scriptPubKey"]["addresses"]:
            if address in myaddresses:
                newtx_inputs.append({"txid":txid,"vout":vout["n"]})
                total_amount += vout["value"]
                break

    print newtx_inputs
    print total_amount
    
    # Now find the sendign addresses, and choose one at random
    # to receive the funds.
    total_inputs = Decimal("0")
    addresses = []
    for vin in tx["vin"]:
        intxid = vin["txid"]
        invout = vin["vout"]

        # Get the outputs of the input transaction
        intx = access.getrawtransaction(intxid,1)
        # print intxid, invout
        vout = intx["vout"][invout]
        # pprint.pprint(vout)
        total_inputs += vout["value"]
        addresses.extend(vout["scriptPubKey"]["addresses"])
    print "Total inputs: %f" % total_inputs
    print addresses
    to_address = random.choice(addresses)

    # Build a transaction with the output of the original transaction as input
    # and to_address as output.
    newtx_hex = access.createrawtransaction(newtx_inputs,{to_address:float(total_amount)})
    newtx_hex = access.signrawtransaction(newtx_hex)["hex"]
    print newtx_hex
    # print >>open("/home/user/a.txt","a"), access.decoderawtransaction(newtx_hex)
    access.sendrawtransaction(newtx_hex)
コード例 #4
0
ファイル: main2.py プロジェクト: tom0927fuj/testnem
def main():
    rpc_user = '******'
    rpc_password = '******'
    rpc = AuthServiceProxy(f'http://{rpc_user}:{rpc_password}@127.0.0.1:18332/')
    #rpc = AuthServiceProxy(f'http://{rpc_user}:{rpc_password}@172.17.0.2:18332/')
    print(rpc.getinfo())
    best_block_hash = rpc.getbestblockhash()
    print(rpc.getblock(best_block_hash))
    blhash = rpc.getblockhash(0) #blhashはブロックのhash文字列
    bl = rpc.getblock(blhash) #blはブロック情報
    print(bl)
    dummy_address = '2MudgRfNaaw96kqAWziZ5JGsPbo2pzQp7Jy'
    change_address = '2NAVrak22jX3DQyDqnoqdm5ZTak1RgXWPzo'

    filename = 'mark_token.btc.json'
    url='https://drive.google.com/file/d/1ZR6Q5sCM_acUpPy7s3d9GJH8I2Plh4FI/view?usp=sharing'

    with open(filename, 'rb') as f:
        data2 = f.read()
    hashdata=hashlib.sha256(data2).hexdigest()
    js={'file_hash':hashdata,'url':url}
    data=json.dumps(js).encode("UTF-8")


    while True:
        if len(data) >= 80:
            buffer = data[:80]
            data = data[80:]
        elif len(data) == 0:
            break
        else:
            buffer = data
            data = b''

        first_unspent = rpc.listunspent()[0]
        txid = first_unspent['txid']
        vout = first_unspent['vout']
        input_amount = first_unspent['amount']
        SATOSHI = Decimal("0.00000001")
        change_amount = input_amount - Decimal("0.005") - SATOSHI

        tx = rpc.createrawtransaction([{"txid": txid, "vout": vout}],[{change_address: change_amount}, {'data': hexlify(buffer).decode('utf-8')}, ])
        tx = rpc.signrawtransactionwithwallet(tx)['hex']
        rpc.sendrawtransaction(tx)

    block_hash = rpc.generatetoaddress(1, change_address)[0]
    block = rpc.getblock(block_hash)
    txs = block['tx'][1:]

    print(f'# of txs: {len(txs)}')
    pprint(txs)

    for tx_hash in txs:
        raw_tx = rpc.gettransaction(tx_hash)['hex']
        decoded_tx = rpc.decoderawtransaction(raw_tx)
        # pprint(decoded_tx)
        print(decoded_tx['vout'][1]['scriptPubKey']['asm'])
コード例 #5
0
class ParsingBlock(Parsing_block):
    def __init__(self,
                 from_block=0,
                 db_name="pars",
                 collection="data3",
                 to_block=-1):
        self.client = ClientHistory()
        self.from_block = from_block
        self.to_block = to_block
        self.qtum = AuthServiceProxy(qtum_server)
        self.db_wallet = Table_new(db_name, collection)

    def check(self, vout):
        try:
            for vout_i in vout:
                try:
                    script_pub_key = vout_i["scriptPubKey"]
                    addresses = script_pub_key["addresses"]
                    value = vout_i["value"]
                    value_float = float(value)
                    value_int = int(value * (10**8))
                    for adr in addresses:
                        data = self.client.getbalance(adr)
                        if data == {'error': 404}:
                            pass
                        else:
                            db_coin = self.db_wallet.insert_new(
                                **{
                                    "adr": adr,
                                    "value": value_int
                                })
                            update_data_1 = self.client.incbalance(
                                adr, value_float)
                            #logging.critical(update_data_1)
                except:
                    pass
        except:
            pass

    def decode_raw_transaction_vout(self, encoded_datas=None):
        try:
            if not encoded_datas:
                encoded_datas = self.get_raw_transaction()
            for encoded_data in encoded_datas:
                transaction_data = self.qtum.decoderawtransaction(encoded_data)
                vin = transaction_data["vin"]
                vout = transaction_data["vout"]
                self.check(vout)
            self.show_db()
        except:
            pass

    def getblockcount(self):
        return self.qtum.getblockcount()
コード例 #6
0
ファイル: blockchain.py プロジェクト: TAIIOK/memechain-api
def create_raw_op_return_transaction(metadata):
    """
    Method used to create a transaction with embedded data through OP_RETURN

    Args:
            metadata (str)

    Returns:
            Raw transaction (hex)
            Author address (str)
    """
    rpc = AuthServiceProxy(
        ("http://%s:%[email protected]:%s/") %
        (config['RPC_USER'], config['RPC_PASS'], config['RPC_PORT']))

    if sys.getsizeof(metadata) > MAX_OP_RETURN_BYTES:
        raise Exception("Metadata size is over MAX_OP_RETURN_BYTES")

    if len(metadata) < 4:
        raise Exception(
            "This tool set does not currently support reading op_return data with less than 4 chars"
        )

    input_tx = get_input()

    init_raw_tx = rpc.createrawtransaction(
        [{
            "txid": input_tx["txid"],
            "vout": input_tx["vout"]
        }], {
            input_tx["address"]:
            TX_BURN_AMOUNT,
            rpc.getnewaddress():
            round(float(input_tx["amount"]) - 1.1 * TX_BURN_AMOUNT, 8)
        })

    oldScriptPubKey = init_raw_tx[len(init_raw_tx) - 60:len(init_raw_tx) - 8]
    newScriptPubKey = b"6a" + hexlify(
        bytes(chr(len(metadata)), encoding='utf-8')) + hexlify(
            bytes(metadata, encoding='utf-8'))
    newScriptPubKey = hexlify(
        bytes(chr(len(unhexlify(newScriptPubKey))),
              encoding='utf-8')) + newScriptPubKey

    if oldScriptPubKey not in init_raw_tx:
        raise Exception("Something broke!")

    op_return_tx = init_raw_tx.replace(oldScriptPubKey,
                                       newScriptPubKey.decode('ascii'))

    print(rpc.decoderawtransaction(op_return_tx)['vout'])

    return op_return_tx, input_tx["address"]
コード例 #7
0
def rpc_loop(ncurses_q, json_q):
	config = ConfigParser.ConfigParser()
	config.read('bitcoind-ncurses.conf')
	rpcuser = config.get('rpc', 'rpcuser')
	rpcpassword = config.get('rpc', 'rpcpassword')
	rpcip = config.get('rpc', 'rpcip')
	rpcport = config.get('rpc', 'rpcport')

	rpcurl = "http://" + rpcuser + ":" + rpcpassword + "@" + rpcip + ":" + rpcport
	rpchandle = AuthServiceProxy(rpcurl, None, 500)

	last_blockcount = 0		# ensures block info is updated initially
	last_update = time.time() - 2
	while 1:
		try: s = json_q.get(False)
		except: s = {}
		
		if 'blockheight' in s:
			blockhash = rpchandle.getblockhash(s['blockheight'])
			blockinfo = rpchandle.getblock(blockhash)
			ncurses_q.put(blockinfo)
			last_blockcount = cur_blockcount
		elif 'txid' in s:
			raw_tx = rpchandle.getrawtransaction(s['txid'])
			decoded_tx = rpchandle.decoderawtransaction(raw_tx)
			ncurses_q.put(decoded_tx)

		if (time.time() - last_update) > 2: 
			info = rpchandle.getinfo()
			ncurses_q.put(info)
		
			nettotals = rpchandle.getnettotals()
			ncurses_q.put(nettotals)
	
			walletinfo = rpchandle.getwalletinfo()
			ncurses_q.put(walletinfo)

			cur_blockcount = info['blocks']
			if (cur_blockcount != last_blockcount):		# minimise RPC calls
				#if (last_blockcount == 0):
				lastblocktime = {'lastblocktime': time.time()}
				ncurses_q.put(lastblocktime)
				
				blockhash = rpchandle.getblockhash(cur_blockcount)
				blockinfo = rpchandle.getblock(blockhash)
				ncurses_q.put(blockinfo)
				last_blockcount = cur_blockcount
			
			last_update = time.time()

		time.sleep(0.5)		# minimise RPC calls
コード例 #8
0
ファイル: main.py プロジェクト: zhangsanfeng1988/FEIP
def block_updater():
	logger = logging.getLogger('Block Updater')
	logger.setLevel(logging.INFO)
	while 1:
		rpc_connection = AuthServiceProxy(config.config["rpc_server_uri"])
		block = rpc_connection.getblock(config.config["current_block"])
		logger.info(f"Update Tip: Block={config.config['current_block']},Height={block['height']}")
		if "confirmations" in block and "nextblockhash" in block:
			config.config["current_block"] = block["nextblockhash"]
			config.save_config()
			for i in block["tx"]:
				tx = rpc_connection.decoderawtransaction(rpc_connection.getrawtransaction(i))
				decode_opreturn_msg(tx, block)
		else:
			time.sleep(6)
コード例 #9
0
class BitcoinCLI:

    def __init__(self):
        self.rpc_connection = AuthServiceProxy(config.endpoint)

    def get_best_block_hash(self):
        return self.rpc_connection.getbestblockhash()

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

    def get_best_block(self):
        return self.rpc_connection.getblock(self.rpc_connection.getbestblockhash())

    def get_block_hash(self, height):
        return self.rpc_connection.getblockhash(height)

    def get_block(self, hash):
        return self.rpc_connection.getblock(hash)
    def get_transaction(self, hash):
        return self.rpc_connection.gettransaction(hash)

    def get_txn_list_from_block(self, hash):
        block = self.get_block(hash)

        if 'tx' in block:
            return block['tx']
        else:
            raise KeyError('Block {0} has no attribute tx'.format(hash))

    def get_raw_transaction(self, tx_id):
        out = self.rpc_connection.getrawtransaction(tx_id, 1)
        return out
    def decoderawtransaction(self, tx_id):
        out = self.rpc_connection.decoderawtransaction(raw)
        return out

    def get_tx_outputs(self, tx_id):
        tx = self.rpc_connection.getrawtransaction(tx_id, 1)
        outputs = [float(i['value']) for i in tx['vout']]
        return outputs

    def get_tx_details(self, tx_id):
        tx = self.rpc_connection.getrawtransaction(tx_id, 1)
        outputs = [float(i['value']) for i in tx['vout']]
        return outputs
コード例 #10
0
ファイル: blockchain.py プロジェクト: TAIIOK/memechain-api
def get_tx_burn_amount(txid):
    """
    Method used to get burn output amount for transactions (for op_return transactions)

    Args:
        Transaction id (str)

    Returns: 
        Sum of input values, i.e. burn amount (float) 
    """
    rpc = AuthServiceProxy(
        ("http://%s:%[email protected]:%s/") %
        (config['RPC_USER'], config['RPC_PASS'], config['RPC_PORT']))

    raw_tx = rpc.getrawtransaction(txid)
    tx_data = rpc.decoderawtransaction(raw_tx)

    for data in tx_data["vout"]:
        if data["scriptPubKey"]["asm"][:9] == "OP_RETURN":
            return data['value']
コード例 #11
0
class LocalBlockchainRPCReader(object):
    """Fetches blockchain data from bitcoind RPC interface."""
    def __init__(self, username=None, password=None, host=None, port=None):
        if None in (username, password, host, port):
            username, password, host, port, _ = get_config_settings()
        self.rpc_connection = AuthServiceProxy(
            "http://%s:%s@%s:%s" % (username, password, host, port))

    def get_block_hash_at_height(self, block_height):
        """Get the hash of the block at the specified height."""
        return self.rpc_connection.getblockhash(block_height)

    def get_json_for_block_hash(self, block_hash):
        """Get a JSON representation of all transactions at specified height."""
        return self.rpc_connection.getblock(block_hash)

    def _get_raw_tx(self, tx_id):
        """Returns tx in raw format.

        If the requested transaction is the sole transaction of the genesis
        block, bitcoind's RPC interface will throw an error 'No information
        available about transaction (code -5)' so we preempt this by raising an
        error. Iterating callers should just move on to the next tx or block.
        """
        if tx_id == (
                '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7af'
                'deda33b'):
            raise NoDataAvailableForGenesisBlockError
        else:
            return self.rpc_connection.getrawtransaction(tx_id)

    def get_decoded_tx(self, tx_id):
        """Returns a human-readable string of the transaction in JSON format."""
        #print "DEBUG: get_decoded_tx %s" % tx_id
        try:
            return self.rpc_connection.decoderawtransaction(
                self._get_raw_tx(tx_id))
        except NoDataAvailableForGenesisBlockError:
            #bitcoind won't generate this, but here's what it would look like
            genesis_json = {
                'txid': ('4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2'
                         '127b7afdeda33b'),
                'version':
                1,
                'locktime':
                0,
                'vin': [{
                    "sequence":
                    4294967295,
                    'coinbase':
                    ('04ffff001d0104455468652054696d65732030332f4a6'
                     '16e2f32303039204368616e63656c6c6f72206f6e2062'
                     '72696e6b206f66207365636f6e64206261696c6f75742'
                     '0666f722062616e6b73')
                }],
                'vout': [{
                    'value': 50.00000000,
                    'n': 0,
                    'scriptPubKey': {
                        'asm': ('04678afdb0fe5548271967f1a67130b7105cd6a828'
                                'e03909a67962e0ea1f61deb649f6bc3f4cef38c4f3'
                                '5504e51ec112de5c384df7ba0b8d578a4c702b6bf1'
                                '1d5f OP_CHECKSIG'),
                        'hex': ('4104678afdb0fe5548271967f1a67130b7105cd6a8'
                                '28e03909a67962e0ea1f61deb649f6bc3f4cef38c4'
                                'f35504e51ec112de5c384df7ba0b8d578a4c702b6b'
                                'f11d5fac'),
                        'reqSigs':
                        1,
                        'type':
                        'pubkey',
                        'addresses': ['1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa']
                    }
                }]
            }
            return genesis_json

    def get_decoded_script(self, asm):
        """Convert bitcoind's 'asm' value to decoded format."""
        return self.rpc_connection.decodescript(asm)
def main():

    # Example
    # -------
    # This asset: https://blockstream.info/liquid/asset/f266a3f15e78b71481adfedff9aefe47c69501a181ffc68527bb5fb26da6a4b2
    # Was issued in transaction: https://blockstream.info/liquid/tx/49cc1ca72be5b5ca3375348274cee22ccb686f4c3a8f8bc7767156680ca61d92
    # Which was included in block: 1038078
    # You can run the script with:
    # ASSET_ID = 'f266a3f15e78b71481adfedff9aefe47c69501a181ffc68527bb5fb26da6a4b2'
    # START_BLOCK_HEIGHT = 1038078
    # STOP_AT_BLOCK_HEIGHT = None
    # That will trawl every block since issuance to check for any reissuances
    # or burns for the asset so you can validate the amounts shown on the
    # liquid assets page above.

    ###########################################################################
    #              BEFORE RUNNING THE SCRIPT SET THE VALUES BELOW
    ###########################################################################

    # REQUIRED
    # --------
    # Elements RPC Credentials
    # You need to change all 3 after setting them in your elements.conf file.
    # See associated README for example config file format.
    RPC_USER = '******'
    RPC_PASSWORD = '******'
    RPC_PORT = 18885

    # BLOCK RANGE CONTROL
    # -------------------
    # The script will save the last block processed to file and will pick up
    # from there if you set this to True. False will ignore the contents of
    # the LAST_BLOCK file and use START_BLOCK_HEIGHT. If there is no
    # LAST_BLOCK file it will use START_BLOCK_HEIGHT.
    START_FROM_LAST_BLOCK_PROCESSED = True

    # If START_FROM_LAST_BLOCK_PROCESSED is False or the script has not been
    # run before you can specify the initial start block height.
    # This may be useful if you know an initial issuance was done at a
    # particular block height and do not need to process earlier blocks.
    # After running the script the last block processed will saved in the file
    # LAST_BLOCK.
    START_BLOCK_HEIGHT = 0

    # Stop processing at a particular block height (inclusive).
    # Set to None to process until chain tip.
    # If a value is given and the value is equal to the value in LAST_BLOCK the
    # script will exit.
    # If a value is given and the value is lower than the height in
    # the LAST_BLOCK_HEIGHT file it will be ignored and the script will run to
    # chain tip.
    STOP_AT_BLOCK_HEIGHT = None

    # OPTIONAL ASSET ID TO LOOK FOR
    # -----------------------------
    # Set the following to an asset hex if you want to report on a specific
    # asset, otherwise leave it as None to report on all assets:
    # Note: the L-BTC asset id is 6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d
    # This script will track burns of L-BTC but not pegs in or out yet.
    ASSET_ID = None

    ###########################################################################
    #              BEFORE RUNNING THE SCRIPT SET THE VALUES ABOVE
    ###########################################################################

    block_count = 0
    block_hash = ''
    rpc_ready = False
    end_of_chain = False
    block_height = START_BLOCK_HEIGHT
    saved_block_height = None

    if START_FROM_LAST_BLOCK_PROCESSED:
        saved_block_height = readLastBlockHeight()
        if saved_block_height:
            if STOP_AT_BLOCK_HEIGHT:
                if saved_block_height > STOP_AT_BLOCK_HEIGHT:
                    # If the last block processed is greater than the stop height
                    # process up to chain tip instead.
                    STOP_AT_BLOCK_HEIGHT = None
                if saved_block_height == STOP_AT_BLOCK_HEIGHT:
                    print(
                        f'LAST_BLOCK value is {saved_block_height} and so is STOP_AT_BLOCK_HEIGHT. Exiting.'
                    )
                    print(
                        f'Note: set STOP_AT_BLOCK_HEIGHT to None to process to chain tip.'
                    )
                    sys.exit()
            if saved_block_height > START_BLOCK_HEIGHT:
                # If the last block processed is greater than the start height
                # process from last block processed. This avoids writing duplicate
                # entries to the asset files.
                block_height = saved_block_height + 1

    message_block_stop_at = 'chain tip'
    if STOP_AT_BLOCK_HEIGHT:
        message_block_stop_at = f'block {str(STOP_AT_BLOCK_HEIGHT)}'

    print(
        f'Will process from block {block_height} to {message_block_stop_at}.')
    print('Do you want to start processing blocks? (y/n)')
    x = input()
    if x.upper() == 'N' or x.upper() == 'No':
        print(f'Exiting.')
        sys.exit()
    print(f'Processing...')

    # Delete any old asset files if we are starting from genesis:
    if block_height == 0:
        removeAssetFiles()

    # Check node is ready for RPC calls
    while not rpc_ready:
        try:
            rpc_connection = AuthServiceProxy(
                f'http://{RPC_USER}:{RPC_PASSWORD}@127.0.0.1:{RPC_PORT}')
            block_count = rpc_connection.getblockcount()
            rpc_ready = True
        except Exception as e:
            print(f'Cannot connect to node or node not ready for RPC: {e}')
            print('Sleeping for 5 seconds...')
            time.sleep(5)

    print('Connected to node using RPC')
    last_existing_block = None

    while not end_of_chain:
        try:
            print(f'Processing block at height {block_height}')
            block_hash = rpc_connection.getblockhash(block_height)
            block = rpc_connection.getblock(block_hash)
            last_existing_block = block_height
            txs = block['tx']

            for tx in txs:
                tx_hash = rpc_connection.getrawtransaction(tx)
                tx_details = rpc_connection.decoderawtransaction(tx_hash)

                #Issuances and Reissuances:
                for vin in tx_details['vin']:
                    issuance = vin.get('issuance')
                    if issuance:
                        if ASSET_ID is None or ASSET_ID == issuance['asset']:
                            print(f"Found asset: {issuance['asset']}")
                            writeIssueOrReissue(issuance, block_height)
                #Burns:
                for vout in tx_details['vout']:
                    vout_value = str(vout.get('value', '0E-8'))
                    if vout_value != '0.00000000' and vout_value != '0E-8':
                        script_pubkey = vout.get('scriptPubKey')
                        if script_pubkey:
                            asm = script_pubkey.get('asm')
                            script_type = script_pubkey.get('type')
                            if asm and script_type:
                                if asm == 'OP_RETURN' and script_type == 'nulldata':
                                    if ASSET_ID is None or ASSET_ID == vout[
                                            'asset']:
                                        writeBurn(vout, block_height)
            if STOP_AT_BLOCK_HEIGHT:
                if STOP_AT_BLOCK_HEIGHT == block_height:
                    end_of_chain = True
            block_height = block_height + 1
        except Exception as e:
            if hasattr(e, 'message'):
                if e.message == 'Block height out of range':
                    print(f'No block at height {block_height}. Stopping.')
                else:
                    print(f'Error: {e.message}')
            else:
                print(f'Error: {e}')
            end_of_chain = True
    if last_existing_block:
        print(
            f'Last block processed was at height {last_existing_block}. Saved last block height to "LAST_BLOCK" file.'
        )
        writeLastBlockHeight(last_existing_block)
コード例 #13
0
                # Find the price data that was the latest before the block was mined
                while not (block['time'] >= (int(row[0])) and block['time'] <= int(row[0])+600):
                    row = next(priceDataReader)
                btcPrice = float(row[7])
                t3 = time.time()

                # Iterate through every tx in a block. Don't want to include the coinbase tx when iterating through
                # each tx in a block
                for txid in block['tx'][1:]:
                    totalIn = 0
                    totalOut = 0
                    rpcLookupCount += 1

                    # Get data of a tx
                    tx = node.decoderawtransaction(node.getrawtransaction(txid), True)

                    try:
                        # Need the total Bitcoins being used as inputs
                        for input in tx['vin']:
                            inputCount += 1
                            rpcLookupCount += 1
                            # Need to know which index of an output of this tx is being spent
                            index = input['vout']
                            # The node only refers to the txid of the output that's being spent in this input, so need to fetch
                            # that first
                            txo = node.decoderawtransaction(node.getrawtransaction(input['txid']), True)
                            # Need to get the actual output of this tx being spent to get the amount
                            totalIn += txo['vout'][index]['value']

                        # Need the total Bitcoins being spent as outputs
コード例 #14
0
class RPCConnection:
    """Creates a continuous connection to the bitcoind RPC interface.

    RPC connections are configured by the configuration file referred to by
    `CONFIG_FILENAME`.

    Attributes:
        conn (`AuthServiceProxy`): A connection to the RPC interface.
    """
    def __init__(self):
        config_parser = ConfigParser.ConfigParser()
        config_parser.read(CONFIG_FILENAME)
        username = config_parser.get(section='RPC', option='rpc_username')
        password = config_parser.get(section='RPC', option='rpc_password')
        host = config_parser.get(section='RPC', option='rpc_host')
        port = config_parser.get(section='RPC', option='rpc_port')

        self.conn = AuthServiceProxy("http://%s:%s@%s:%s" %
                                     (username, password, host, port))

    def get_block_hash_at_height(self, block_height):
        """Get the hash of the block at the specified block height."""
        return self.conn.getblockhash(block_height)

    def get_json_for_block_hash(self, block_hash):
        """Get a JSON represntation of the specified block."""
        return self.conn.getblock(block_hash)

    def get_tx_ids_at_height(self, block_height):
        """Get a list of transaction IDs contained in the specified block."""
        block_hash = self.get_block_hash_at_height(block_height)
        tx_json = self.get_json_for_block_hash(block_hash)
        tx_ids = []
        for tx_id in tx_json['tx']:
            tx_ids.append(tx_id)
        return tx_ids

    def get_raw_tx(self, tx_id):
        """Return transaction in raw format.

        If the requested transaction is the sole transaction of the genesis
        block, bitcoind's RPC interface will throw an error 'No information
        available about transaction (code -5)' so we preempt this by raising a
        custom error that callers should handle; iterating callers should just
        move onto the next tx.
        """
        if tx_id == (
                '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7af'
                'deda33b'):
            raise IndexError
        else:
            return self.conn.getrawtransaction(tx_id)

    def get_decoded_tx(self, tx_id):
        """Gets the transaction in JSON format from the RPC interface."""
        try:
            return self.conn.decoderawtransaction(self.get_raw_tx(tx_id))
        except IndexError:
            #bitcoind won't generate this, but here's what it would look like
            genesis_json = {
                'txid': ('4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2'
                         '127b7afdeda33b'),
                'version':
                1,
                'locktime':
                0,
                'vin': [{
                    "sequence":
                    4294967295,
                    'coinbase':
                    ('04ffff001d0104455468652054696d65732030332f4a6'
                     '16e2f32303039204368616e63656c6c6f72206f6e2062'
                     '72696e6b206f66207365636f6e64206261696c6f75742'
                     '0666f722062616e6b73')
                }],
                'vout': [{
                    'value': 50.00000000,
                    'n': 0,
                    'scriptPubKey': {
                        'asm': ('04678afdb0fe5548271967f1a67130b7105cd6a828'
                                'e03909a67962e0ea1f61deb649f6bc3f4cef38c4f3'
                                '5504e51ec112de5c384df7ba0b8d578a4c702b6bf1'
                                '1d5f OP_CHECKSIG'),
                        'hex': ('4104678afdb0fe5548271967f1a67130b7105cd6a8'
                                '28e03909a67962e0ea1f61deb649f6bc3f4cef38c4'
                                'f35504e51ec112de5c384df7ba0b8d578a4c702b6b'
                                'f11d5fac'),
                        'reqSigs':
                        1,
                        'type':
                        'pubkey',
                        'addresses': ['1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa']
                    }
                }]
            }
            return genesis_json
コード例 #15
0
ファイル: base.py プロジェクト: walletmona/coinunifier
class WalletBase:

    def __init__(self, pay_tx_fee, min_tx_fee,
                 prio_threshold, dust_soft_limit, free_tx_size):
        self.proxy = None
        self.pay_tx_fee = pay_tx_fee
        self.min_tx_fee = min_tx_fee
        self.prio_threshold = prio_threshold
        self.dust_soft_limit = dust_soft_limit
        self.free_tx_size = free_tx_size

    def set_size(self, base_size, input_size, output_size):
        self.base_size = base_size
        self.input_size = input_size
        self.output_size = output_size

    def load_config(self, config_path):
        # trick to load a config file without sections
        con = open(config_path, 'r').read()
        dummy_fp = io.StringIO(("[%s]\n" % TMP_SECTION) + con)
        config = configparser.ConfigParser()
        config.readfp(dummy_fp)

        ## utility function
        def get_conf(key, default=None):
            if config.has_option(TMP_SECTION, key):
                return config.get(TMP_SECTION, key)
            return default

        self.rpc_user = get_conf('rpcuser')
        self.rpc_pass = get_conf('rpcpassword')
        self.rpc_port = int(get_conf('rpcport'))
        self.rpc_host = get_conf('rpcconnect', '127.0.0.1')

        if config.has_option(TMP_SECTION, 'paytxfee'):
            self.pay_tx_fee = int(float(get_conf('paytxfee')) * 10**8)
        if config.has_option(TMP_SECTION, 'mintxfee'):
            self.min_tx_fee = int(float(get_conf('mintxfee')) * 10**8)

    def connect(self):
        self.proxy = AuthServiceProxy('http://%s:%s@%s:%d/' %
                                      (self.rpc_user, self.rpc_pass,
                                       self.rpc_host, self.rpc_port))

    def get_size(self, inputs, outputs):
        raw = self.proxy.createrawtransaction(inputs, outputs)
        return len(raw) / 2

    ## Deprecate after official supports for getrawchangeaddress in major coins
    def get_change_address(self):
        groups = self.proxy.listaddressgroupings()
        for group in groups:
            for entry in group:
                if len(entry) == 3:
                    ## maybe with account
                    continue
                elif len(entry) == 2:
                    res = self.proxy.validateaddress(entry[0])
                    if 'account' not in res:
                        return entry[0]
                else:
                    raise RuntimeError('never reach')
        return self.proxy.getnewaddress()

    ## ref: wallet.cpp CWallet::CreateTransaction
    def calculate(self, inputs, address, amount, chgaddress):
        tmp = {address: float(amount) / 10**8, chgaddress: 1 }
        size = self.get_size(inputs, tmp)

        total = 0
        prio = 0
        for inp in inputs:
            raw = self.proxy.getrawtransaction(inp['txid'])
            tx = self.proxy.decoderawtransaction(raw)
            value = tx['vout'][inp['vout']]['value']
            conf = self.proxy.gettransaction(inp['txid'])['confirmations']

            total += int(value * 10**8)
            prio += int(value * 10**8) * (conf + 1)
        prio = int(prio / size)

        payfee = self.pay_tx_fee * (1 + int(size / 1000))

        minfee = self.min_tx_fee * (1 + int(size / 1000))
        if prio >= self.prio_threshold and size < self.free_tx_size:
            minfee = 0
        if amount < self.dust_soft_limit:
            minfee += self.min_tx_fee
        if total-amount-minfee < self.dust_soft_limit:
            minfee += self.min_tx_fee
        fee = max(payfee, minfee)

        change = total - amount - fee

        if change <= 0:
            raise RuntimeError('Insufficient inputs: change = %f' %
                               (float(change) / 10**8))

        return { 'total': total, 'fee': fee, 'change': change,
                  'size': size, 'prio': prio }

    def send(self, inputs, address, amount):
        chgaddress = self.get_change_address()
        res = self.calculate(inputs, address, amount, chgaddress)
        outputs = { address: float(amount) / 10**8,
                    chgaddress: float(res['change']) / 10**8 }

        raw = self.proxy.createrawtransaction(inputs, outputs)
        signed = self.proxy.signrawtransaction(raw)
        if not signed['complete']:
            raise RuntimeError('signatures are missing')
        return self.proxy.sendrawtransaction(signed['hex'])

    def show_send_info(self, inputs, address, amount):
        chgaddress = self.get_change_address()
        res = self.calculate(inputs, address, amount, chgaddress)

        print('Total amount: %f' % (float(res['total']) / 10**8))
        print('Send: %f to %s' % (float(amount) / 10**8, address))
        print('Change: %f to %s' % (float(res['change']) / 10**8, chgaddress))
        print('Fee: %f' % (float(res['fee']) / 10**8))
        print('Size: %d bytes' % res['size'])
        print('Priority: %d' % res['prio'])

    def unspent_coins(self):
        coins = self.proxy.listunspent(6)
        for c in coins:
            c['amount'] = int(c['amount'] * 10**8)
            c['prio'] = c['amount'] * (c['confirmations'] + 1)
        return coins
コード例 #16
0
 curblock = curblock + 1
 totalblk = rpcpipe.getblockcount()
 if (curblock > totalblk - txnconf):
     with open('/root/moonaudit/progress.dat', 'w') as progress:
         progress.write(str(curblock - 1))
         progress.closed
         exit()
 rawblockhash = rpcpipe.getblockhash(curblock)
 rawblockdata = rpcpipe.getblock(rawblockhash)
 print 'checking block %08d' % (curblock)
 timestamp = find_between(str(rawblockdata), 'time\': ', ', u\'bits')
 sendnum = 0
 for txhash in rawblockdata['tx']:
     sendnum = sendnum + 1
     txraw = rpcpipe.getrawtransaction(txhash)
     txdata = rpcpipe.decoderawtransaction(txraw)
     curvout = -1
     for outputs in txdata['vout']:
         curvout = curvout + 1
         address = ''
         value = 0
         address = find_between(str(outputs), '[u\'', '\']')
         value = find_between(str(outputs), 'Decimal(\'', '\')')
         if (float(str(value)) > 28999999.99999999):
             print 'block number: %08d;' % (
                 curblock,
             ) + ' unixtime: ' + timestamp + '; address: ' + address + '; coins sent in one operation: ' + str(
                 value) + '; txid of transaction: ' + txhash
             with open('/var/www/moonsend_working.log', 'a') as moonaudit:
                 moonaudit.write(
                     'block number: %08d;' % (curblock, ) + ' unixtime: ' +
コード例 #17
0
print("Wallet Info:")
print("-----------")
pprint(wallet_info)
print("---------------------------------------------------------------\n")

## List UTXOs

utxos = rpc_client.listunspent()
print("Utxos: ")
print("-----")
pprint(utxos)
print("------------------------------------------\n")

## Select a UTXO - first one selected here

utxo_txid = utxos[0]['txid']

## Get UTXO Hex

utxo_hex = rpc_client.gettransaction(utxo_txid)['hex']

## Get tx Details

utxo_tx_details = rpc_client.decoderawtransaction(utxo_hex)
print("Details of Utxo with txid:", utxo_txid)
print("---------------------------------------------------------------")
print("UTXO Details:")
print("------------")
pprint(utxo_tx_details)
print("---------------------------------------------------------------\n")
コード例 #18
0
ファイル: Parsing.py プロジェクト: chris0203/pmes
class Parsing_block():
    def __init__(self,
                 from_block=0,
                 to_block=-1,
                 db_name="pars",
                 collection="wallet7"):
        self.from_block = from_block
        self.to_block = to_block
        self.qtum = AuthServiceProxy("http://%s:%[email protected]:8333" %
                                     ("qtumuser", "qtum2018"))
        self.db_wallet = Table_new(db_name, collection)

    def block_hash_num(self, block=None):
        try:
            if not block:
                block = self.from_block
            block_hash = self.qtum.getblockhash(block)
            return block_hash
        except:
            pass

    def get_transaction_in_block(self, block_hash=None):
        try:
            if not block_hash:
                block_hash = self.block_hash_num()
            block = self.qtum.getblock(block_hash)
            list_tx = block["tx"]
            return list_tx
        except:
            pass

    def get_raw_transaction(self, transaction_blocks=None):
        try:
            if not transaction_blocks:
                transaction_blocks = self.get_transaction_in_block()
            transaction_list = []
            for transaction_block in transaction_blocks:
                try:
                    transaction_data = self.qtum.getrawtransaction(
                        transaction_block)
                except JSONRPCException:
                    try:
                        send_data = self.qtum.sendrawtransaction(
                            transaction_block)
                        pprint(send_data)
                    except JSONRPCException:
                        pass
                else:
                    transaction_list += [transaction_data]
            return transaction_list
        except:
            pass

    '''
    def insert_db(self, vout):

        for vout_i in vout:
            try:
                n_dict = {}
                script_pub_key = vout_i["scriptPubKey"]
                addresses = script_pub_key["addresses"]
                value = vout_i["value"]
                n = vout_i["n"]
                n_str = str(n)
                list_adr = []
                for iter_adr in addresses:
                    list_adr += [{iter_adr: value}]
                n_dict[n_str] = list_adr
                print(n_dict)

            except KeyError:
                pass
    '''

    def transaction_in(self, vin):
        try:
            for vin_i in vin:
                try:
                    txid = vin_i["txid"]
                    vout_num = vin_i["vout"]
                    encoded_datas = self.get_raw_transaction([txid])
                    for i in encoded_datas:
                        transaction_data = self.qtum.decoderawtransaction(i)
                        vout_prev = transaction_data["vout"]
                        vout_prev_data = vout_prev[vout_num]
                        value_dec = vout_prev_data["value"]
                        script_pub_key = vout_prev_data["scriptPubKey"]
                        addresses = script_pub_key["addresses"]
                        value_int = int(value_dec * (10**8))
                        for address in addresses:
                            news = self.db_wallet.update_inc(
                                address, "value", -value_int)
                except KeyError:
                    pass
        except:
            pass

    def transaction_out(self, vout):
        try:
            for vout_i in vout:
                try:
                    script_pub_key = vout_i["scriptPubKey"]
                    addresses = script_pub_key["addresses"]
                    value = vout_i["value"]
                    value_int = int(value * (10**8))
                    for adr in addresses:
                        if not self.db_wallet.find({'id': adr}):
                            data = self.db_wallet.insert(adr, **{"value": 0})
                        news = self.db_wallet.update_inc(
                            adr, "value", value_int)
                        #self.db_wallet.delete(adr)
                except KeyError:
                    pass
        except:
            pass

    def decode_raw_transaction(self, encoded_datas=None):
        try:
            if not encoded_datas:
                encoded_datas = self.get_raw_transaction()
            for encoded_data in encoded_datas:
                transaction_data = self.qtum.decoderawtransaction(encoded_data)
                vin = transaction_data["vin"]
                vout = transaction_data["vout"]
                self.transaction_out(vout)
                self.transaction_in(vin)
        except:
            pass

    def show_db(self):
        return self.db_wallet.show_db()
コード例 #19
0
ファイル: getblockdata.py プロジェクト: j-s/getblockdata
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException

# rpc_user and rpc_password are set in the bitcoin.conf file
rpc_btc = AuthServiceProxy("http://%s:%[email protected]:8332"%('rpc_user', 'rpc_password'))
blockchain = open('blockchain.txt', 'ab+') #you will need to make this blank file in your python folder before running the program
for i in range(1,416570,1): #the range of blocks to grab data for, in this case blocks 1 to 416570, incrementing 1 block at a time
        get_block_hash = rpc_btc.getblockhash(i)
        block = rpc_btc.getblock(get_block_hash)
        coinbase = rpc_btc.decoderawtransaction(rpc_btc.getrawtransaction(block['tx'][0]))
        value = coinbase['vout'][0]['value'] #this gets total block reward
        print(i)
        blockchain.write(str(block['height'])+', '+str(value)+', '+str(block['hash'])+', '+str(block['size'])+', '+str(len(block['tx']))+', '+str(block['version'])+', '+str(block['merkleroot'])+', '+str(block['time'])+', '+str(block['nonce'])+', '+str(block['bits'])+', '+str(block['difficulty'])+', '+str(block['chainwork'])+'\n')
blockchain.close()
print('done')
コード例 #20
0
class SearchTransaction():
    def __init__(self, from_block=0, qtum_host=qtum_host_def):
        self.qtum = AuthServiceProxy(qtum_host)
        self.from_block = from_block
        self.client = self.conection_stor()
        self.balance = ClientBalance(balance_server)

    def abi_to_params(self, abi, output_types):
        decode_hex = codecs.getdecoder("hex_codec")
        encode_hex = codecs.getencoder("hex_codec")
        data = decode_hex(abi)[0]
        return decode_abi(output_types, data)

    def search_transaction(self, txid, address_smart_contract, vouts):
        signatures = {'8c3ce5d7': ['makeCid({0[0]}, {0[1]}, {0[2]}, {0[3]}, {0[4]})',
                                   ['string', 'address', 'string', 'uint256', 'uint256'],
                                   self.new_cid],

                      '65d72416': ['newOffer({0[0]}, {0[1]}, {0[2]}, {0[3]}, {0[4]})',
                                   ['uint256', 'address', 'uint256', 'uint256', 'string'],
                                   self.new_offer],

                      '715c084b': ['sellContent({0[0]}, {0[1]}, {0[2]})',
                                   ['uint256', 'address', 'string', 'string'],
                                   self.confirm_balance],

                      'bbfd5e53': ['changeOwner({0[0]}, {0[1]}, {0[2]})',
                                   ['uint256', 'address', 'string', 'string'],
                                   self.confirm_balance],

                      '41309af4': ["newReview({0[0]}, {0[1]}, {0[2]}, {0[3]})",
                                   ["uint256", "address", "string"],
                                   self.update_review],

                      'a9059cbb': ["",
                                   ['address', 'uint'],
                                   self.balance_put]

                      }
        list_data = []
        # hex_block = self.qtum.getrawtransaction(txid)
        # decode_block = self.qtum.decoderawtransaction(hex_block)
        # pprint(decode_block)
        # vouts = decode_block["vout"]
        for vout in vouts:
            script_pub_key = vout["scriptPubKey"]
            types = script_pub_key["type"]
            if types == "call":
                asm = script_pub_key["asm"]
                asm_split = asm.split()
                asm_data = asm_split[3]
                smart_contr_address = asm_split[4]
                if smart_contr_address in address_smart_contract:
                    hex_address = asm_data[:8]
                    data = asm_data[8:]
                    signatures_list = signatures[hex_address]
                    signatures_list_type = signatures_list[1]
                    # signatures_list_text = signatures_list[0]
                    # print(data, signatures_list_type)
                    try:
                        decode = self.abi_to_params(data, signatures_list_type)
                        new_decode = self.change_decode(signatures_list_type, decode)
                        data_write = [txid] + new_decode
                        method = signatures_list[2]
                        method_call = method(data_write)
                        # print(map(signatures_list[2], data))
                        # print(data)
                        # decode_string = signatures_list_text.format(new_decode)
                        # print(decode_string)
                        list_data += data
                    except Exception as e:
                        print(e)

        return list_data

    def change_decode(self, signatures_list_type, decode):
        decode = list(decode)
        if "address" in signatures_list_type:
            index_adr = signatures_list_type.index("address")
            decode_index_adr = decode[index_adr]
            new_adr = decode_index_adr[2:]
            decode[index_adr] = new_adr
        if "string" in signatures_list_type:
            index_str = signatures_list_type.index("string")
            decode_index_str = decode[index_str]
            new_str = decode_index_str.decode()
            decode[index_str] = new_str
        return decode

    def block_hash_num(self, block=None):
        # get block hash
        try:
            if not block:
                block = self.from_block
            block_hash = self.qtum.getblockhash(block)
            return block_hash
        except:
            pass

    def get_transaction_in_block(self, block_hash=None):
        # get list transaction in block
        try:
            if not block_hash:
                block_hash = self.block_hash_num()
            block = self.qtum.getblock(block_hash)
            list_tx = block["tx"]
            return list_tx
        except:
            pass

    def get_raw_transaction(self, transaction_blocks=None):
        # get raw transaction
        try:
            if not transaction_blocks:
                transaction_blocks = self.get_transaction_in_block()
            transaction_list = []
            for transaction_block in transaction_blocks:
                try:
                    transaction_data = [self.qtum.getrawtransaction(transaction_block)]
                    transaction_data += [transaction_block]
                    transaction_list += [transaction_data]
                except JSONRPCException:
                    try:
                        transaction_data = [self.qtum.gettransaction(transaction_block)]
                        transaction_data += [transaction_block]
                        transaction_list += [transaction_data]
                    except JSONRPCException:
                        pass
                        # print(transaction_block)
            return transaction_list
        except:
            pass

    def decode_raw_transaction(self, address_smart_contract, encoded_datas=None):
        # decode raw transaction
        try:
            if not encoded_datas:
                try:
                    encoded_datas = self.get_raw_transaction()
                except:
                    pass
            for encoded_data in encoded_datas:
                try:
                    # encoded_data = encoded_datas[2]
                    # print(encoded_data)
                    transaction_data = self.qtum.decoderawtransaction(encoded_data[0])

                    # print(transaction_data)
                    # vin = transaction_data["vin"]
                    # print(vin)
                    txid = encoded_data[1]
                    vout = transaction_data["vout"]
                    # print(vout)
                    result = self.search_transaction(txid, address_smart_contract, vout)
                except:
                    pass
        except:
            pass

    def balance_put(self, data):
        txid = data[0]
        address = data[1]
        address = Qtum.hex_to_qtum_address(address, mainnet=False)
        ammount = data[2]
        check = self.balance.get_balance(address, "PUT")
        if type(check) == list:
            update_data_1 = self.balance.inc_balance(address, ammount, "PUT")

    def new_cid(self, data):
        tx_hash = data[0]
        cid = data[1]
        result = self.client.update_users_content(txid=tx_hash)

    def new_offer(self, data):
        txid = data[0]
        cid = data[1]
        address = data[2]
        offer_type = data[3]
        price = data[4]
        self.client.update_offer(txid)
        mail = self.client.mailed_confirm(cid=cid, buyer_address=address, offer_type=offer_type, price=price)

    def confirm_balance(self, data):
        tx_hash = data[0]
        cid = data[1]
        address = data[2]
        result = self.balance.confirm_balance(txid=tx_hash, cid=cid, buyer_address=address)

    def update_review(self, data):
        txid = data[0]
        self.client.update_review(txid)

    def conection_stor(self):
        while True:
            try:
                cli = ClientStorge(storghost)
                return cli
            except:
                sleep(1)

    def run(self, from_i, address_smart_contract):
        while True:
            getlastblock = self.qtum.getblockcount()
            # print(getlastblock)
            if getlastblock >= from_i:
                pars = SearchTransaction(from_i)
                result = pars.decode_raw_transaction(address_smart_contract)
                print(from_i)
                from_i += 1
            else:
                sleep(1)
コード例 #21
0
class RPCConnection:
    """Creates a continuous connection to the bitcoind RPC interface.

    RPC connections are configured by the configuration file referred to by
    `CONFIG_FILENAME`.

    Attributes:
        conn (`AuthServiceProxy`): A connection to the RPC interface.
    """
    def __init__(self):
        config_parser = ConfigParser.ConfigParser()
        config_parser.read(CONFIG_FILENAME)
        username = config_parser.get(section='RPC', option='rpc_username')
        password = config_parser.get(section='RPC', option='rpc_password')
        host = config_parser.get(section='RPC', option='rpc_host')
        port = config_parser.get(section='RPC', option='rpc_port')

        self.conn = AuthServiceProxy("http://%s:%s@%s:%s" %
                                     (username, password, host, port))

    def get_block_hash_at_height(self, block_height):
        """Get the hash of the block at the specified block height."""
        return self.conn.getblockhash(block_height)

    def get_json_for_block_hash(self, block_hash):
        """Get a JSON represntation of the specified block."""
        return self.conn.getblock(block_hash)

    def get_tx_ids_at_height(self, block_height):
        """Get a list of transaction IDs contained in the specified block."""
        block_hash = self.get_block_hash_at_height(block_height)
        tx_json = self.get_json_for_block_hash(block_hash)
        tx_ids = []
        for tx_id in tx_json['tx']:
            tx_ids.append(tx_id)
        return tx_ids

    def get_raw_tx(self, tx_id):
        """Return transaction in raw format.

        If the requested transaction is the sole transaction of the genesis
        block, bitcoind's RPC interface will throw an error 'No information
        available about transaction (code -5)' so we preempt this by raising a
        custom error that callers should handle; iterating callers should just
        move onto the next tx.
        """
        if tx_id == ('4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7af'
                     'deda33b'):
            raise IndexError
        else:
            return self.conn.getrawtransaction(tx_id)

    def get_decoded_tx(self, tx_id):
        """Gets the transaction in JSON format from the RPC interface."""
        try:
            return self.conn.decoderawtransaction(self.get_raw_tx(tx_id))
        except IndexError:
            #bitcoind won't generate this, but here's what it would look like
            genesis_json = {
                'txid':    ('4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2'
                            '127b7afdeda33b'),
                'version':  1,
                'locktime': 0,
                'vin': [{
                    "sequence":4294967295,
                    'coinbase': ('04ffff001d0104455468652054696d65732030332f4a6'
                                 '16e2f32303039204368616e63656c6c6f72206f6e2062'
                                 '72696e6b206f66207365636f6e64206261696c6f75742'
                                 '0666f722062616e6b73')
                }],
                'vout': [
                    {
                        'value': 50.00000000,
                        'n': 0,
                        'scriptPubKey': {
                            'asm': ('04678afdb0fe5548271967f1a67130b7105cd6a828'
                                    'e03909a67962e0ea1f61deb649f6bc3f4cef38c4f3'
                                    '5504e51ec112de5c384df7ba0b8d578a4c702b6bf1'
                                    '1d5f OP_CHECKSIG'),
                            'hex': ('4104678afdb0fe5548271967f1a67130b7105cd6a8'
                                    '28e03909a67962e0ea1f61deb649f6bc3f4cef38c4'
                                    'f35504e51ec112de5c384df7ba0b8d578a4c702b6b'
                                    'f11d5fac'),
                            'reqSigs': 1,
                            'type': 'pubkey',
                            'addresses': ['1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa']
                        }
                    }
                ]
            }
            return genesis_json
コード例 #22
0
		cht = os.popen('%s %s -create in=%s:%d:%s:%d outaddr=%s:"%s"' % (sidechain_tx_path, "-testnet" if is_testnet == 1 else "", args.sidechainClaimTx, 0, str(prev_out["value"]), 0x100000000 - int(prev_script[9]) - 1, str(prev_out["value"]), sidechain.getnewaddress()))
		tx_hex = cht.read().split("\n")[0]
		assert(cht.close() == None)

		tx_hex = sidechain.signrawtransaction(tx_hex, [{"txid": args.sidechainClaimTx, "vout": 0, "scriptPubKey": prev_out["scriptPubKey"]["hex"], "redeemScript": p2sh_res["redeemScript"], "nValue": prev_out["serValue"]}], [sidechain.dumpprivkey(args.sidechainAddress)])
		if tx_hex["complete"] != True:
			print("Got incomplete transaction (signing failed to create spendable transaction):")
			print(tx_hex["hex"])
		else:
			print("Submitting tx to mempool...")
			sidechain.sendrawtransaction(tx_hex["hex"])
			print("Success!")

	elif args.command == "send-to-mainchain":
		p2sh_tx_test = bitcoin.decoderawtransaction(bitcoin.createrawtransaction([], {args.p2shMainAddress: 0.1}))["vout"][0]["scriptPubKey"]
		if p2sh_tx_test["type"] != "scripthash":
			print("You must use a P2SH address")
			exit(1)
		p2sh_hex = p2sh_tx_test["asm"].split(" ")[1]

		cht = os.popen('%s -create outscript=%s:"0x1850325348%s OP_DROP 0x20%s 0x14%s WITHDRAWPROOFVERIFY"' % (sidechain_tx_path, args.coinAmt, p2sh_hex, inverse_bitcoin_genesis_hash, secondScriptPubKeyHash))
		res_tx = cht.read().split("\n")[0]
		assert(cht.close() == None)

		donation = sidechain.fundrawtransaction(res_tx)["fee"]
		if donation > 0:
			if donation < 550: # Probably dust
				donation = 550
			cht = os.popen('%s -create outscript=%s:"0x1850325348%s OP_DROP 0x20%s 0x14%s WITHDRAWPROOFVERIFY" outscript=%s:"RETURN"' % (sidechain_tx_path, args.coinAmt, p2sh_hex, inverse_bitcoin_genesis_hash, secondScriptPubKeyHash, str(Decimal(donation) / Decimal(100000000))))
			res_tx = cht.read().split("\n")[0]
コード例 #23
0
ファイル: ChainX.intf.py プロジェクト: yujiye/ChainBlockchain
class chainxdSSH(object):
    def __init__(self, host, port, username):
        self.host = host
        self.port = port
        self.username = username
        self.ssh = None
        self.channel = None
        self.fw_channel = None
        self.connected = False
        self.ssh_thread = None

    def __del__(self):
        self.disconnect()

    def remote_command(self, cmd):
        channel = None
        try:
            channel = self.ssh.get_transport().open_session()
            channel.exec_command(cmd)
            ret_code = channel.recv_exit_status()

            if ret_code == 0:
                for idx in range(1, 20):
                    if channel.recv_ready():
                        break
                    time.sleep(0.1)
                if not channel.recv_ready():
                    raise Exception('Data not ready')
                data = channel.recv(500)
                return data.decode().split('\n')
            else:
                for idx in range(1, 20):
                    if channel.recv_stderr_ready():
                        break
                    time.sleep(0.1)
                if channel.recv_stderr_ready():
                    data = channel.recv_stderr(500)
                    error = data.decode()
                    raise Exception(error)
                else:
                    raise UnknownError('Unknown error executing remote command: ' + cmd)
        finally:
            if channel:
                channel.close()

    def connect(self):
        import paramiko
        self.ssh = paramiko.SSHClient()
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        password = None
        pass_message = None

        while True:
            try:
                self.ssh.connect(self.host, port=int(self.port), username=self.username, password=password)
                self.connected = True
                if password:
                    SshPassCache.save_password(self.username, self.host, password)
                break
            except PasswordRequiredException as e:
                # private key with password protection is used; ask user for password
                pass_message = "Enter passphrase for <b>private key</b> or password for %s" % \
                               (self.username + '@' + self.host)
                while True:
                    password = SshPassCache.get_password(self.username, self.host, message=pass_message)
                    if password:
                        break
                        chain_port = self.remote_port

            except AuthenticationException as e:
                # This exception will be raised in the following cases:
                #  1. a private key with password protectection is used but the user enters incorrect password
                #  2. a private key exists but user's public key is not added to the server's allowed keys
                #  3. normal login to server is performed but the user enters bad password
                # So, in the first case, the second query for password will ask for normal password to server, not
                #  for a private key.

                WndUtils.errorMsg(message='Incorrect password, try again...')

                while True:
                    password = SshPassCache.get_password(self.username, self.host, message=pass_message)
                    if password:
                        break

            except SSHException as e:
                if e.args and e.args[0] == 'No authentication methods available':
                    while True:
                        password = SshPassCache.get_password(self.username, self.host)
                        if password:
                            break
                else:
                    raise
            except Exception as e:
                raise

    def open_tunnel(self, local_port, remote_ip, remote_port):
        if self.connected:
            ready_event = threading.Event()
            self.ssh_thread = SSHTunnelThread(local_port, remote_ip, remote_port, self.ssh.get_transport(), ready_event)
            self.ssh_thread.start()
            ready_event.wait(10)
            print('Started local port forwarding 127.0.0.1:%s -> %s:%s' %
                  (str(local_port), remote_ip, str(remote_port)))
        else:
            raise Exception('SSH not connected')

    

        self.config = config
        # conn configurations are used from the first item in the list; if one fails, then next is taken
        if connection:
            # this parameter is used for testing specific connection
            self.connections = [connection]
        else:
            # get connection list orderd by priority of use
            self.connections = self.config.get_ordered_conn_list()
        self.cur_conn_index = 0
        if self.connections:
            self.cur_conn_def = self.connections[self.cur_conn_index]
        else:
            self.cur_conn_def = None

        # below is the connection with which particular RPC call has started; if connection is switched because of
        # problems with some nodes, switching stops if we close round and return to the starting connection
        self.starting_conn = None

        self.ssh = None
        self.window = window
        self.active = False
        self.rpc_url = None
        self.proxy = None
        self.http_conn = None  # HTTPConnection object passed to the AuthServiceProxy (for convinient connection reset)
        self.on_connection_begin_callback = on_connection_begin_callback
        self.on_connection_try_fail_callback = on_connection_try_fail_callback
        self.on_connection_finished_callback = on_connection_finished_callback
        self.last_error_message = None

    def apply_new_cfg(self):
        """
        Called after any of connection config changed.
        """
        # get connection list orderd by priority of use
        self.disconnect()
        self.connections = self.config.get_ordered_conn_list()
        self.cur_conn_index = 0
        if not len(self.connections):
            raise Exception('There is no connections to chainx network enabled in the configuration.')
        self.cur_conn_def = self.connections[self.cur_conn_index]

    def disconnect(self):
        if self.active:
            if self.ssh:
                self.ssh.disconnect()
                del self.ssh
                self.ssh = None
            self.active = False

    def mark_call_begin(self):
        self.starting_conn = self.cur_conn_def

    def switch_to_next_config(self):
        """
        If there is another chainxd config not used recently, switch to it. Called only when there was a problem
        with current connection config.
        :return: True if successfully switched ot False if there was no another config
        """
        if self.cur_conn_def:
            self.config.conn_cfg_failure(self.cur_conn_def)  # mark connection as defective
        if self.cur_conn_index < len(self.connections)-1:
            idx = self.cur_conn_index + 1
        else:
            idx = 0

        conn = self.connections[idx]
        if conn != self.starting_conn:
            self.disconnect()
            self.cur_conn_index = idx
            self.cur_conn_def = conn
            if not self.open():
                return self.switch_to_next_config()
            else:
                return True
        else:
            return False

    def mark_cur_conn_cfg_is_ok(self):
        if self.cur_conn_def:
            self.config.conn_cfg_success(self.cur_conn_def)

    def open(self):
        """
        Opens connection to chainx RPC. If it fails, then the next enabled conn config will be used, if any exists.
        :return: True if successfully connected, False if user cancelled the operation. If all of the attempts 
            fail, then appropriate exception will be raised.
        """
        try:
            if not self.cur_conn_def:
                raise Exception('There is no connections to chainx network enabled in the configuration.')

            while True:
                try:
                    if self.open_internal():
                        break
                    else:
                        if not self.switch_to_next_config():
                            return False
                except UserCancelledConnection:
                    return False
                except (socket.gaierror, ConnectionRefusedError, TimeoutError, socket.timeout) as e:
                    # exceptions raised by not likely functioning chainxd node; try to switch to another node
                    # if there is any in the config
                    if not self.switch_to_next_config():
                        raise e  # couldn't use another conn config, raise exception
                    else:
                        break
        except Exception as e:
            self.last_error_message = str(e)
            raise

        return True

    def open_internal(self):
        """
        Try to establish connection to chainxd RPC daemon for current connection config.
        :return: True, if connection successfully establishes, False if user Cancels the operation (not always 
            cancelling will be possible - only when user is prompted for a password).
        """
        if not self.active:
            if self.cur_conn_def.use_ssh_tunnel:
                # RPC over SSH
                while True:
                    self.ssh = ChainxdSSH(self.cur_conn_def.ssh_conn_cfg.host, self.cur_conn_def.ssh_conn_cfg.port,
                                        self.cur_conn_def.ssh_conn_cfg.username)
                    try:
                        logging.info('starting ssh.connect')
                        self.ssh.connect()
                        logging.info('finished ssh.connect')
                        break
                    except Exception as e:
                        logging.error('error in ssh.connect')
                        raise

                # configure SSH tunnel
                # get random local unprivileged port number to establish SSH tunnel
                success = False
                local_port = None
                for try_nr in range(1, 10):
                    try:
                        logging.info('beginning ssh.open_tunnel')
                        local_port = randint(2000, 50000)
                        self.ssh.open_tunnel(local_port,
                                             self.cur_conn_def.host,
                                             int(self.cur_conn_def.port))
                        success = True
                        break
                    except Exception as e:
                        logging.error('error in ssh.open_tunnel loop')
                        pass
                logging.info('finished ssh.open_tunnel loop')
                if not success:
                    logging.error('finished ssh.open_tunnel loop with error')
                    return False
                else:
                    rpc_user = self.cur_conn_def.username
                    rpc_password = self.cur_conn_def.password
                    rpc_host = '127.0.0.1'  # SSH tunnel on loopback
                    rpc_port = local_port
            else:
                # direct RPC
                rpc_host = self.cur_conn_def.host
                rpc_port = self.cur_conn_def.port
                rpc_user = self.cur_conn_def.username
                rpc_password = self.cur_conn_def.password

            if self.cur_conn_def.use_ssl:
                self.rpc_url = 'https://'
                self.http_conn = httplib.HTTPSConnection(rpc_host, rpc_port, timeout=5, context=ssl._create_unverified_context())
            else:
                self.rpc_url = 'http://'
                self.http_conn = httplib.HTTPConnection(rpc_host, rpc_port, timeout=5)

            logging.info('AuthServiceProxy begin')
            self.rpc_url += rpc_user + ':' + rpc_password + '@' + rpc_host + ':' + str(rpc_port)
            self.proxy = AuthServiceProxy(self.rpc_url, timeout=1000, connection=self.http_conn)
            logging.info('AuthServiceProxy end')

            try:
                if self.on_connection_begin_callback:
                    try:
                        # make the owner know, we are connecting
                        logging.info('on_connection_begin_callback begin')
                        self.on_connection_begin_callback()
                        logging.info('on_connection_begin_callback end')
                    except:
                        pass

                # check the connection
                logging.info('starting http_conn.connect()')
                self.http_conn.connect()
                logging.info('finished http_conn.connect()')

                if self.on_connection_finished_callback:
                    try:
                        # make the owner know, we successfully finished connection
                        self.on_connection_finished_callback()
                    except:
                        pass
            except:
                if self.on_connection_try_fail_callback:
                    try:
                        # make the owner know, connection attempt failed
                        self.on_connection_try_fail_callback()
                    except:
                        pass
                raise
            finally:
                logging.info('http_conn.close()')
                self.http_conn.close()
                # timeout hase been initially set to 5 seconds to perform 'quick' connection test
                self.http_conn.timeout = 20

            self.active = True
        return self.active

    def get_active_conn_description(self):
        if self.cur_conn_def:
            return self.cur_conn_def.get_description()
        else:
            return '???'

    @control_rpc_call
    def getblockcount(self):
        if self.open():
            return self.proxy.getblockcount()
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getblockhash(self, block):
        if self.open():
            return self.proxy.getblockhash(block)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getinfo(self):
        if self.open():
            return self.proxy.getinfo()
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def issynchronized(self):
        if self.open():
            # if connecting to HTTP(S) proxy do not check if chainxd daemon is synchronized
            if self.cur_conn_def.is_http_proxy():
                return True
            else:
                syn = self.proxy.mnsync('status')
                return syn.get('IsSynced')
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def mnsync(self):
        if self.open():
            # if connecting to HTTP(S) proxy do not call this function - it will not be exposed
            if self.cur_conn_def.is_http_proxy():
                return {}
            else:
                return self.proxy.mnsync('status')
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def masternodebroadcast(self, what, hexto):
        if self.open():
            return self.proxy.masternodebroadcast(what, hexto)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def get_masternodelist(self, *args):
        if self.open():
            return self.proxy.masternodelist(*args)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def get_masternodeaddr(self):
        if self.open():
            return self.proxy.masternodelist('addr')
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getaddressbalance(self, address):
        if self.open():
            return self.proxy.getaddressbalance({'addresses': [address]}).get('balance')
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getaddressutxos(self, addresses):
        if self.open():
            return self.proxy.getaddressutxos({'addresses': addresses})
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getrawtransaction(self, txid, verbose):
        if self.open():
            return self.proxy.getrawtransaction(txid, verbose)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getblockhash(self, blockid):
        if self.open():
            return self.proxy.getblockhash(blockid)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getblockheader(self, blockhash):
        if self.open():
            return self.proxy.getblockheader(blockhash)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def validateaddress(self, address):
        if self.open():
            return self.proxy.validateaddress(address)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def decoderawtransaction(self, tx):
        if self.open():
            return self.proxy.decoderawtransaction(tx)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def sendrawtransaction(self, tx):
        if self.open():
            return self.proxy.sendrawtransaction(tx)
        else:
            raise Exception('Not connected')
コード例 #24
0
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
import json
import time

# rpc_user and rpc_password are set in the bitcoin.conf file
rpc_doge = AuthServiceProxy("http://%s:%[email protected]:22555"%('dogecoinrpcuser', 'dogecoinrpcpassword'))

outset = set()
cache = set()
while True:
	mempool = rpc_doge.getrawmempool()
	for item in mempool:
		if item not in cache:
			cache.add(item)
			tx = rpc_doge.decoderawtransaction(rpc_doge.getrawtransaction(item))
			for i in range(0,len(tx['vout']),1):
				try:
					out = (tx['vout'][i]['value'])
					outset.add(out)
				except:
					continue
			if len(str(int(round(sum(outset),-1)))) == 1:
				print(''+str(int(round(sum(outset,-1)))))
			elif len(str(int(round(sum(outset),-1)))) == 2:
				print(' /\\')
				print(' '+str(int(round(sum(outset,-1)))))
				print(' \\/')
			elif len(str(int(round(sum(outset),-1)))) == 3:
				print('    _')
				print('   / \\')
				print('   '+str(int(round(sum(outset,-1)))))
コード例 #25
0
ファイル: Parsing.py プロジェクト: codyli2002hk/pmes
class ParsingBlock():
    """ Parsing all transaction in all blocks
    """
    def __init__(self, from_block=0, to_block=-1, db_host=None, db_name=None):
        self.from_block = from_block
        self.to_block = to_block
        self.coinid = coin_id
        self.qtum = AuthServiceProxy(qtum_server)
        self.client = ClientBalance(settings.balanceurl)
        self.db = TablePars(db_host, db_name)
        self.storge = ClientStorge(settings.storageurl)

    def block_hash_num(self, block=None):
        # get block hash
        try:
            if not block:
                block = self.from_block
            block_hash = self.qtum.getblockhash(block)
            return block_hash
        except:
            pass

    def get_transaction_in_block(self, block_hash=None):
        # get list transaction in block
        try:
            if not block_hash:
                block_hash = self.block_hash_num()
            block = self.qtum.getblock(block_hash)
            list_tx = block["tx"]
            return list_tx
        except:
            pass

    def get_raw_transaction(self, transaction_blocks=None):
        # get raw transaction
        try:
            if not transaction_blocks:
                transaction_blocks = self.get_transaction_in_block()
            transaction_list = []
            for transaction_block in transaction_blocks:
                try:
                    transaction_data = self.qtum.getrawtransaction(
                        transaction_block)
                    transaction_list += [transaction_data]
                except JSONRPCException:
                    try:
                        transaction_data = self.qtum.gettransaction(
                            transaction_block)
                        transaction_list += [transaction_data]
                    except JSONRPCException:
                        pass
            return transaction_list
        except:
            pass

    def transaction_in(self, vin):
        # parsing input
        try:
            list_address = []
            for vin_i in vin:
                try:
                    txid = vin_i["txid"]
                    vout_num = vin_i["vout"]
                    encoded_datas = self.get_raw_transaction([txid])
                    for i in encoded_datas:
                        try:
                            transaction_data = self.qtum.decoderawtransaction(
                                i)
                            vout_prev = transaction_data["vout"]
                            vout_prev_data = vout_prev[vout_num]
                            value_dec = vout_prev_data["value"]
                            script_pub_key = vout_prev_data["scriptPubKey"]
                            addresses = script_pub_key["addresses"]
                            value_int = int(value_dec * (10**8))
                            for adr in addresses:
                                list_address += [{adr: value_int}]
                        except:
                            pass
                except:
                    pass
            return list_address
        except:
            pass

    def transaction_out(self, vout, txid):
        # parsing output
        try:
            list_address = [False]
            for vout_i in vout:
                try:
                    script_pub_key = vout_i["scriptPubKey"]
                    types = script_pub_key["type"]
                    if types == "call" and self.coinid == coin_id:
                        asm = script_pub_key["asm"]
                        asm_split = asm.split()
                        gasLimit = asm_split[1]
                        gasPrice = asm_split[2]
                        asm_data = asm_split[3]
                        hex_address = asm_data[:8]
                        smart_contr_address = asm_split[4]
                        if smart_contr_address in address_smart_contract and hex_address == sign_transfer:
                            data = asm_data[8:]
                            signatures_list_type = ['address', 'uint']
                            try:
                                decode = self.abi_to_params(
                                    data, signatures_list_type)
                                new_decode = self.change_decode(
                                    signatures_list_type, decode)
                                address_token = new_decode[0]
                                value_int = new_decode[1]
                                address_token = Qtum.hex_to_qtum_address(
                                    address_token, mainnet=mainnet_status)
                                result = self.db.check_address(
                                    address=address_token, coinid=coin_id_put)
                                result_keys = result.keys()
                                if "address" in result_keys:
                                    update_data_1 = self.client.inc_balance(
                                        address_token, value_int, coin_id_put)
                                    self.storge.log_transaction(
                                        **{
                                            "coinid": coin_id_put,
                                            "blocknumber": self.from_block,
                                            "blockhash": self.block_hash_num(),
                                            "vin": [],
                                            "vout": [{
                                                address_token: value_int
                                            }],
                                            "txid": txid,
                                            "gasLimit": gasLimit,
                                            "gasPrice": gasPrice
                                        })
                            except Exception as e:
                                # print(e)
                                pass
                    addresses = script_pub_key["addresses"]
                    value = vout_i["value"]
                    value_int = int(value * (10**8))
                    for adr in addresses:
                        data = self.db.check_address(adr, self.coinid)
                        result_keys = data.keys()
                        if "address" in result_keys:
                            update_data_1 = self.client.inc_balance(
                                adr, value_int, coin_id)
                            list_address[0] = True
                        list_address += [{adr: value_int}]
                except:
                    pass
            return list_address
        except:
            pass

    def decode_raw_transaction(self, encoded_datas=None):
        # decode raw transaction
        try:
            if not encoded_datas:
                encoded_datas = self.get_raw_transaction()
            for encoded_data in encoded_datas:
                try:
                    transaction_data = self.qtum.decoderawtransaction(
                        encoded_data)
                    # vin = transaction_data["vin"]
                    vout = transaction_data["vout"]
                    txid = transaction_data["txid"]
                    # self.transaction_in(vin)
                    vout_res = self.transaction_out(vout, txid)
                    if vout_res[0]:
                        vin_res = self.transaction_in(transaction_data["vin"])
                        self.storge.log_transaction(
                            **{
                                "coinid": self.coinid,
                                "blocknumber": self.from_block,
                                "blockhash": self.block_hash_num(),
                                "vin": vin_res,
                                "vout": vout_res[1:],
                                "txid": txid
                            })
                except:
                    pass
        except:
            pass

    def change_decode(self, signatures_list_type, decode):
        decode = list(decode)
        if "address" in signatures_list_type:
            index_adr = signatures_list_type.index("address")
            decode_index_adr = decode[index_adr]
            new_adr = decode_index_adr[2:]
            decode[index_adr] = new_adr
        if "string" in signatures_list_type:
            index_str = signatures_list_type.index("string")
            decode_index_str = decode[index_str]
            new_str = decode_index_str.decode()
            decode[index_str] = new_str
        return decode

    def abi_to_params(self, abi, output_types):
        decode_hex = codecs.getdecoder("hex_codec")
        encode_hex = codecs.getencoder("hex_codec")
        data = decode_hex(abi)[0]
        return decode_abi(output_types, data)

    def get_block_count(self):
        # Get count documents in db
        return self.qtum.getblockcount()
コード例 #26
0
    inputsList.append({
        "txid": u["txid"],
        "vout": u["vout"],
        "address": changeAddress
    })
    inputsWithScriptKeysList.append({
        "txid": u["txid"],
        "vout": u["vout"],
        "scriptPubKey": u["scriptPubKey"]
    })

# createrawtransaction [{"txid":txid,"vout":n},...] {address:amount,...}
print()
logger.info("Creating tx hash going to address {}...".format(toAddresses))
createTxHex = rpcConnection.createrawtransaction(inputsList, toAddresses)
createTxJson = rpcConnection.decoderawtransaction(createTxHex)
if len(createTxHex.strip()) > 0:
    # pprint(rpcConnection.decodescript(createTxHex));
    # pprint(rpcConnection.decoderawtransaction(createTxHex));
    createTxID = createTxJson["txid"]
    logger.info(
        "TX was successfulling created. TxID is: {}".format(createTxID))
else:
    logger.error("Failed to create tx. Aborting.")
    exit()

# signrawtransaction <hex string> [{"txid":txid,"vout":n,"scriptPubKey":hex,"redeemScript":hex},...] [<privatekey1>,...] [sighashtype="ALL"]
print()
logger.info("Signing tx...")
signTxResult = rpcConnection.signrawtransaction(createTxHex,
                                                inputsWithScriptKeysList)
コード例 #27
0
                "redeemScript": p2sh_res["redeemScript"],
                "nValue": prev_out["serValue"]
            }], [sidechain.dumpprivkey(args.sidechainAddress)])
        if tx_hex["complete"] != True:
            print(
                "Got incomplete transaction (signing failed to create spendable transaction):"
            )
            print(tx_hex["hex"])
        else:
            print("Submitting tx to mempool...")
            sidechain.sendrawtransaction(tx_hex["hex"])
            print("Success!")

    elif args.command == "send-to-mainchain":
        p2sh_tx_test = bitcoin.decoderawtransaction(
            bitcoin.createrawtransaction(
                [], {args.p2shMainAddress: 0.1}))["vout"][0]["scriptPubKey"]
        if p2sh_tx_test["type"] != "scripthash":
            print("You must use a P2SH address")
            exit(1)
        p2sh_hex = p2sh_tx_test["asm"].split(" ")[1]

        cht = os.popen(
            '%s -create outscript=%s:"0x1850325348%s OP_DROP 0x20%s 0x14%s WITHDRAWPROOFVERIFY"'
            % (sidechain_tx_path, args.coinAmt, p2sh_hex,
               inverse_bitcoin_genesis_hash, secondScriptPubKeyHash))
        res_tx = cht.read().split("\n")[0]
        assert (cht.close() == None)

        donation = sidechain.fundrawtransaction(res_tx)["fee"]
        if donation > 0:
コード例 #28
0
class DaemonBTC:
    def __init__(self, url, timeout=90):
        self.rpc = AuthServiceProxy(url, timeout=timeout)

    def get_block(self, i):
        block = self.rpc.getblockhash(i)
        block_data = self.rpc.getblock(block)
        block_data['transactions'] = len(block_data['tx'])
        # Elasticsearch struggles with these as integers
        #block_data['chainwork_int'] = int(block_data['chainwork'], 16)
        block_data['difficulty'] = int(block_data['difficulty'])
        del (block_data['tx'])

        # Figure out how many coins moved
        value = 0
        txs = self.get_block_transactions(i)

        # This is the data we need for value
        # txs[0]['vout'][0]['value']
        for tx in txs:
            for vout in tx['vout']:
                if vout['scriptPubKey']['type'] == 'nonstandard':
                    pass
                else:
                    value = value + vout['value']

        block_data['value'] = value

        return block_data

    def get_transaction(self, tx):
        rtx = self.rpc.getrawtransaction(tx)
        dtx = self.rpc.decoderawtransaction(rtx)

        return dtx

    def get_transactions(self, txs):
        rtx = self.rpc.batch_([["getrawtransaction", t] for t in txs])
        dtx = self.rpc.batch_([["decoderawtransaction", t] for t in rtx])

        return dtx

    def get_block_transactions(self, block):

        # The genesis block is special
        if block == 0:
            return []

        blockhash = self.rpc.getblockhash(block)
        block_data = self.rpc.getblock(blockhash)

        transactions = []

        rtx = self.rpc.batch_([["getrawtransaction", t]
                               for t in block_data['tx']])
        dtx = self.rpc.batch_([["decoderawtransaction", t] for t in rtx])

        for tx in dtx:
            tx['height'] = block_data['height']
            tx['block'] = block_data['hash']
            tx['time'] = block_data['time']

            # We can't use this data, let's get rid of it
            for i in tx['vin']:
                if 'scriptSig' in i:
                    del (i['scriptSig'])
            for i in tx['vout']:
                if 'hex' in i['scriptPubKey']:
                    del (i['scriptPubKey']['hex'])
                if 'asm' in i['scriptPubKey']:
                    del (i['scriptPubKey']['asm'])

            transactions.append(tx)

        return transactions

    def get_block_transactions_bulk(self, block):
        "Return an iterable object for bulk transactions"

        transactions = self.get_block_transactions(block)
        tx = Transactions()
        for i in transactions:
            tx.add_transaction(i)

        return tx

    def get_blocks_bulk(self, blocks):

        rbh = self.rpc.batch_([["getblockhash", t] for t in blocks])

        dbh = self.rpc.batch_([["get_block", t] for t in rbh])

        output = []
        for block_data in dbh:
            block_data['transactions'] = len(block_data['tx'])
            block_data['chainwork_int'] = int(block_data['chainwork'], 16)
            del (block_data['tx'])
            output.append(block_data)

        return output

    def get_max_block(self):
        return self.rpc.getblockcount()
コード例 #29
0
class RpcClient:
        
    def __init__(self):
        self.rpc_ip, self.rpc_port, self.rpc_user, self.rpc_passwd = readRPCfile()
        rpc_url = "http://%s:%s@%s:%d" % (self.rpc_user, self.rpc_passwd, self.rpc_ip, self.rpc_port)
        try:    
            self.conn = AuthServiceProxy(rpc_url, timeout=8)     
        except JSONRPCException as e:
            err_msg = 'remote or local PIVX-cli running?'
            printException(getCallerName(), getFunctionName(), err_msg, e)
        except Exception as e:
            err_msg = 'remote or local PIVX-cli running?'
            printException(getCallerName(), getFunctionName(), err_msg, e)
            
    
    
    
    def decodeRawTransaction(self, rawTx):
        try:
            return self.conn.decoderawtransaction(rawTx)    
        except Exception as e:
            err_msg = 'error in decodeRawTransaction'
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            
    
    
    
    def getAddressUtxos(self, addresses):
        try:
            return self.conn.getaddressutxos({'addresses': addresses})    
        except Exception as e:
            err_msg = "error in getAddressUtxos"
            if str(e.args[0]) != "Request-sent":
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
            else:
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
            raise e
    
    
    
    
    def getBlockCount(self):
        try:
            n = self.conn.getblockcount()
            return n
        except Exception as e:
            err_msg = 'remote or local PIVX-cli running?'
            if str(e.args[0]) != "Request-sent":
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
            else:
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
    
    
    
    
    def getBlockHash(self, blockNum):
        try:
            h = self.conn.getblockhash(blockNum)
            return h
        except Exception as e:
            err_msg = 'remote or local PIVX-cli running?'
            if str(e.args[0]) != "Request-sent":
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
            else:
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
    
    
    def getFeePerKb(self):
        try:
            # get transaction data from last 10 blocks
            feePerKb = float(self.conn.getfeeinfo(10)['feeperkb'])
            return (feePerKb if feePerKb > MINIMUM_FEE else MINIMUM_FEE)
        except Exception as e:
            err_msg = 'error in getFeePerKb'
            if str(e.args[0]) != "Request-sent":
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
            else:
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
    
    
    
    def getMNStatus(self, address):
        try:
            mnStatusList = self.conn.listmasternodes(address)
            if not mnStatusList:
                return None
            mnStatus = mnStatusList[0]
            mnStatus['mnCount'] = self.conn.getmasternodecount()['enabled']
            return mnStatus
        
        except Exception as e:
            err_msg = "error in getMNStatus"
            if str(e.args[0]) != "Request-sent":
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
            else:
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
    
    
    
    
    def getProtocolVersion(self):
        try:
            prot_version = self.conn.getinfo().get('protocolversion')
            return int(prot_version)
        
        except Exception as e:
            err_msg = 'error in getProtocolVersion'
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            return DEFAULT_PROTOCOL_VERSION    
     
            
    
    
    def getRawTransaction(self, txid):
        try:
            return self.conn.getrawtransaction(txid)
        except Exception as e:
            err_msg = "is Blockchain synced?"
            if str(e.args[0]) != "Request-sent":
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
            return None
    
    
    
    
    def getStatus(self):
        status = False
        n = 0
        try:
            n = self.conn.getblockcount()
            if n > 0:
                status = True
                
        except Exception as e:
            # If loading block index set lastBlock=1
            if str(e.args[0]) == "Loading block index..." or str(e.args[0]) == "Verifying blocks...":
                printDbg(str(e.args[0]))
                n = 1
            #else:
                #err_msg = "Error while contacting RPC server"
                #printException(getCallerName(), getFunctionName(), err_msg, e.args)    
        return status, n
    
    
    
    
    def getStatusMess(self, status=None):
        if status == None:
            status = self.getStatus()    
        if status: 
            return "RPC status: CONNECTED!!!"
        else:
            return "RPC status: NOT CONNECTED. remote or local PIVX-cli running?"
    
    
    
    def isBlockchainSynced(self):
        try:
            return self.conn.mnsync('status').get("IsBlockchainSynced")
        
        except Exception as e:
            err_msg = "error in isBlockchainSynced"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            return False
            
            
            
    def decodemasternodebroadcast(self, work):
        try:
            return self.conn.decodemasternodebroadcast(work.strip())
        
        except Exception as e:
            err_msg = "error in decodemasternodebroadcast"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            return ""
            
            
    
    def relaymasternodebroadcast(self, work):
        try:
            return self.conn.relaymasternodebroadcast(work.strip())
        
        except Exception as e:
            err_msg = "error in relaymasternodebroadcast"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)    
            return ""


    def sendRawTransaction(self, tx_hex):
        try:
            tx_id = self.conn.sendrawtransaction(tx_hex)
            return tx_id
        except Exception as e:
            err_msg = 'error in rpcClient.sendRawTransaction'
            if str(e.args[0]) != "Request-sent":
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
            else:
                printException(getCallerName(), getFunctionName(), err_msg, e.args)
    
    
    
    
    def verifyMessage(self, pivxaddress, signature, message):
        try:
            return self.conn.verifymessage(pivxaddress, signature, message)
        
        except Exception as e:
            err_msg = "error in verifyMessage"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            
コード例 #30
0
class FullNode:

    def __init__(self, conf_dir=None, rpcuser=None, rpcpassword=None, rpcport=None, rpchost='127.0.0.1', network="main"):
        if rpcport is None:
            rpcport = {'main':8332,'test':18332,'stn':9332, 'regtest':18332}[network]
        if conf_dir is None:
            if platform.system() == 'Darwin':
                conf_dir = os.path.expanduser('~/Library/Application Support/Bitcoin/')
            elif platform.system() == 'Windows':
                conf_dir = os.path.join(os.environ['APPDATA'], 'Bitcoin')
            else:
                conf_dir = os.path.expanduser('~/.bitcoin')

        if network == 'regtest':
            conf_dir = os.path.join(conf_dir, 'regtest')
        if network == 'test':
            conf_dir = os.path.join(conf_dir, 'testnet3')
        elif network == 'stn':
            conf_dir = os.path.join(conf_dir, 'stn')

        if rpcuser is None:
            cookie = os.path.join(conf_dir, '.cookie')
            with open(cookie) as f:
                rpcuserpass = f.read()

        # Use cookie if no rpcuser specified
        if rpcuser:
            uri = "http://{}:{}@{}:{}".format(rpcuser, rpcpassword, rpchost, rpcport)
        else:
            uri = "http://{}@{}:{}".format(rpcuserpass, rpchost, rpcport)

        self.network = network
        self.conf_dir = conf_dir
        self.uri = uri
        self.rpc = AuthServiceProxy(self.uri)
        self.rpcport = rpcport
        self.rpchost = rpchost
        self.network = network

        rpcnet = self.rpc.getblockchaininfo()['chain']
        if rpcnet != network:
            raise ValueError("rpc server is on '%s' network, you passed '%s'" % (rpcnet, network))

    def __getattr__(self, rpc_method):
        return RPCMethod(rpc_method, self)

    def __dir__(self):
        fulllist = []
        fulllist.extend(bitsv_methods)
        fulllist.extend(standardmethods)
        fulllist.extend(self.__dict__.keys())
        return fulllist

    def rpc_connect(self):
        return AuthServiceProxy(self.uri)

    def rpc_reconnect(self):
        self.rpc = AuthServiceProxy(self.uri)

    class Decorators:

        @classmethod
        def handle_broken_pipe(cls, f):
            @wraps(f)
            def reconnect_if_needed(self, *args, **kwargs):
                try:
                    return f(self, *args, **kwargs)
                except BrokenPipeError:
                    self.rpc_reconnect()  # reconnect and try again
                    return f(self, *args)

            return reconnect_if_needed

    @Decorators.handle_broken_pipe
    def get_balance(self, address):
        return sum(unspent.amount for unspent in self.get_unspents(address))

    @Decorators.handle_broken_pipe
    def get_transactions(self, address):
        acct = self.rpc.getaccount(address)
        txs = self.rpc.listtransactions(acct)
        txids = (tx['txid'] for tx in txs)
        txids = list(txids)
        return txids

    @Decorators.handle_broken_pipe
    def get_transaction(self, txid):
        rawtx = self.rpc.getrawtransaction(txid)
        txjson = self.rpc.decoderawtransaction(rawtx)
        inputs = []
        outputs = []
        amount_in = 0
        amount_out = 0
        for vin in txjson['vin']:
            src = self.rpc.getrawtransaction(vin['txid'], True)
            src = self.rpc.decoderawtransaction(src['hex'])
            src = src['vout'][vin['vout']]
            addr = None
            if 'addresses' in src['scriptPubKey']:
                addr = src['scriptPubKey']['addresses'][0]
            amount = int((src['value'] * BSV_TO_SAT_MULTIPLIER).normalize())
            amount_in += amount
            part = TxInput(addr, amount)
            inputs += [part]

        for vout in txjson['vout']:
            addr = None
            if 'addresses' in vout['scriptPubKey']:
                addr = vout['scriptPubKey']['addresses'][0]
            amount = int((vout['value'] * BSV_TO_SAT_MULTIPLIER).normalize())
            amount_out += amount
            part = TxOutput(addr, amount, asm=vout['scriptPubKey']['asm'])
            outputs += [part]

        tx = Transaction(txjson['txid'], amount_in, amount_out)
        for part in inputs:
            tx.add_input(part)
        for part in outputs:
            tx.add_output(part)
        return tx

    @Decorators.handle_broken_pipe
    def get_unspents(self, address):
        unspents = self.rpc.listunspent(0, 9999999, [address], True)
        return [Unspent(
            amount=int((tx['amount'] * BSV_TO_SAT_MULTIPLIER).normalize()),
            confirmations=tx['confirmations'],
            script=tx['scriptPubKey'],
            txid=tx['txid'],
            txindex=tx['vout']
        ) for tx in unspents]

    @Decorators.handle_broken_pipe
    def send_transaction(self, tx_hex):
        return self.rpc.sendrawtransaction(tx_hex, True)
コード例 #31
0
class DashdInterface(WndUtils):
    def __init__(self,
                 config,
                 window,
                 connection=None,
                 on_connection_begin_callback=None,
                 on_connection_try_fail_callback=None,
                 on_connection_finished_callback=None):
        WndUtils.__init__(self, app_path=config.app_path)
        assert isinstance(config, AppConfig)

        self.config = config
        # conn configurations are used from the first item in the list; if one fails, then next is taken
        if connection:
            # this parameter is used for testing specific connection
            self.connections = [connection]
        else:
            # get connection list orderd by priority of use
            self.connections = self.config.get_ordered_conn_list()
        self.cur_conn_index = 0
        if self.connections:
            self.cur_conn_def = self.connections[self.cur_conn_index]
        else:
            self.cur_conn_def = None

        # below is the connection with which particular RPC call has started; if connection is switched because of
        # problems with some nodes, switching stops if we close round and return to the starting connection
        self.starting_conn = None

        self.ssh = None
        self.window = window
        self.active = False
        self.rpc_url = None
        self.proxy = None
        self.http_conn = None  # HTTPConnection object passed to the AuthServiceProxy (for convinient connection reset)
        self.on_connection_begin_callback = on_connection_begin_callback
        self.on_connection_try_fail_callback = on_connection_try_fail_callback
        self.on_connection_finished_callback = on_connection_finished_callback
        self.last_error_message = None

    def apply_new_cfg(self):
        """
        Called after any of connection config changed.
        """
        # get connection list orderd by priority of use
        self.disconnect()
        self.connections = self.config.get_ordered_conn_list()
        self.cur_conn_index = 0
        if not len(self.connections):
            raise Exception(
                'There is no connections to Dash network enabled in the configuration.'
            )
        self.cur_conn_def = self.connections[self.cur_conn_index]

    def disconnect(self):
        if self.active:
            if self.ssh:
                self.ssh.disconnect()
                del self.ssh
                self.ssh = None
            self.active = False

    def mark_call_begin(self):
        self.starting_conn = self.cur_conn_def

    def switch_to_next_config(self):
        """
        If there is another dashd config not used recently, switch to it. Called only when there was a problem
        with current connection config.
        :return: True if successfully switched ot False if there was no another config
        """
        if self.cur_conn_def:
            self.config.conn_cfg_failure(
                self.cur_conn_def)  # mark connection as defective
        if self.cur_conn_index < len(self.connections) - 1:
            idx = self.cur_conn_index + 1
        else:
            idx = 0

        conn = self.connections[idx]
        if conn != self.starting_conn:
            self.disconnect()
            self.cur_conn_index = idx
            self.cur_conn_def = conn
            if not self.open():
                return self.switch_to_next_config()
            else:
                return True
        else:
            return False

    def mark_cur_conn_cfg_is_ok(self):
        if self.cur_conn_def:
            self.config.conn_cfg_success(self.cur_conn_def)

    def open(self):
        """
        Opens connection to dash RPC. If it fails, then the next enabled conn config will be used, if any exists.
        :return: True if successfully connected, False if user cancelled the operation. If all of the attempts 
            fail, then appropriate exception will be raised.
        """
        try:
            if not self.cur_conn_def:
                raise Exception(
                    'There is no connections to Dash network enabled in the configuration.'
                )

            while True:
                try:
                    if self.open_internal():
                        break
                    else:
                        if not self.switch_to_next_config():
                            return False
                except UserCancelledConnection:
                    return False
                except (socket.gaierror, ConnectionRefusedError, TimeoutError,
                        socket.timeout) as e:
                    # exceptions raised by not likely functioning dashd node; try to switch to another node
                    # if there is any in the config
                    if not self.switch_to_next_config():
                        raise e  # couldn't use another conn config, raise exception
                    else:
                        break
        except Exception as e:
            self.last_error_message = str(e)
            raise

        return True

    def open_internal(self):
        """
        Try to establish connection to dash RPC daemon for current connection config.
        :return: True, if connection successfully establishes, False if user Cancels the operation (not always 
            cancelling will be possible - only when user is prompted for a password).
        """
        if not self.active:
            if self.cur_conn_def.use_ssh_tunnel:
                # RPC over SSH
                while True:
                    self.ssh = DashdSSH(
                        self.cur_conn_def.ssh_conn_cfg.host,
                        self.cur_conn_def.ssh_conn_cfg.port,
                        self.cur_conn_def.ssh_conn_cfg.username)
                    try:
                        logging.info('starting ssh.connect')
                        self.ssh.connect()
                        logging.info('finished ssh.connect')
                        break
                    except Exception as e:
                        logging.error('error in ssh.connect')
                        raise

                # configure SSH tunnel
                # get random local unprivileged port number to establish SSH tunnel
                success = False
                local_port = None
                for try_nr in range(1, 10):
                    try:
                        logging.info('beginning ssh.open_tunnel')
                        local_port = randint(2000, 50000)
                        self.ssh.open_tunnel(local_port,
                                             self.cur_conn_def.host,
                                             int(self.cur_conn_def.port))
                        success = True
                        break
                    except Exception as e:
                        logging.error('error in ssh.open_tunnel loop')
                        pass
                logging.info('finished ssh.open_tunnel loop')
                if not success:
                    logging.error('finished ssh.open_tunnel loop with error')
                    return False
                else:
                    rpc_user = self.cur_conn_def.username
                    rpc_password = self.cur_conn_def.password
                    rpc_host = '127.0.0.1'  # SSH tunnel on loopback
                    rpc_port = local_port
            else:
                # direct RPC
                rpc_host = self.cur_conn_def.host
                rpc_port = self.cur_conn_def.port
                rpc_user = self.cur_conn_def.username
                rpc_password = self.cur_conn_def.password

            if self.cur_conn_def.use_ssl:
                self.rpc_url = 'https://'
                self.http_conn = httplib.HTTPSConnection(
                    rpc_host,
                    rpc_port,
                    timeout=5,
                    context=ssl._create_unverified_context())
            else:
                self.rpc_url = 'http://'
                self.http_conn = httplib.HTTPConnection(rpc_host,
                                                        rpc_port,
                                                        timeout=5)

            logging.info('AuthServiceProxy begin')
            self.rpc_url += rpc_user + ':' + rpc_password + '@' + rpc_host + ':' + str(
                rpc_port)
            self.proxy = AuthServiceProxy(self.rpc_url,
                                          timeout=1000,
                                          connection=self.http_conn)
            logging.info('AuthServiceProxy end')

            try:
                if self.on_connection_begin_callback:
                    try:
                        # make the owner know, we are connecting
                        logging.info('on_connection_begin_callback begin')
                        self.on_connection_begin_callback()
                        logging.info('on_connection_begin_callback end')
                    except:
                        pass

                # check the connection
                logging.info('starting http_conn.connect()')
                self.http_conn.connect()
                logging.info('finished http_conn.connect()')

                if self.on_connection_finished_callback:
                    try:
                        # make the owner know, we successfully finished connection
                        self.on_connection_finished_callback()
                    except:
                        pass
            except:
                if self.on_connection_try_fail_callback:
                    try:
                        # make the owner know, connection attempt failed
                        self.on_connection_try_fail_callback()
                    except:
                        pass
                raise
            finally:
                logging.info('http_conn.close()')
                self.http_conn.close()
                # timeout hase been initially set to 5 seconds to perform 'quick' connection test
                self.http_conn.timeout = 20

            self.active = True
        return self.active

    def get_active_conn_description(self):
        if self.cur_conn_def:
            return self.cur_conn_def.get_description()
        else:
            return '???'

    @control_rpc_call
    def getblockcount(self):
        if self.open():
            return self.proxy.getblockcount()
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getblockhash(self, block):
        if self.open():
            return self.proxy.getblockhash(block)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getinfo(self):
        if self.open():
            return self.proxy.getinfo()
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def issynchronized(self):
        if self.open():
            # if connecting to HTTP(S) proxy do not check if dash daemon is synchronized
            if self.cur_conn_def.is_http_proxy():
                return True
            else:
                syn = self.proxy.mnsync('status')
                return syn.get('IsSynced')
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def mnsync(self):
        if self.open():
            # if connecting to HTTP(S) proxy do not call this function - it will not be exposed
            if self.cur_conn_def.is_http_proxy():
                return {}
            else:
                return self.proxy.mnsync('status')
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def masternodebroadcast(self, what, hexto):
        if self.open():
            return self.proxy.masternodebroadcast(what, hexto)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def get_masternodelist(self, *args):
        if self.open():
            return self.proxy.masternodelist(*args)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def get_masternodeaddr(self):
        if self.open():
            return self.proxy.masternodelist('addr')
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getaddressbalance(self, address):
        if self.open():
            return self.proxy.getaddressbalance({
                'addresses': [address]
            }).get('balance')
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getaddressutxos(self, addresses):
        if self.open():
            return self.proxy.getaddressutxos({'addresses': addresses})
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getrawtransaction(self, txid, verbose):
        if self.open():
            return self.proxy.getrawtransaction(txid, verbose)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getblockhash(self, blockid):
        if self.open():
            return self.proxy.getblockhash(blockid)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def getblockheader(self, blockhash):
        if self.open():
            return self.proxy.getblockheader(blockhash)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def validateaddress(self, address):
        if self.open():
            return self.proxy.validateaddress(address)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def decoderawtransaction(self, tx):
        if self.open():
            return self.proxy.decoderawtransaction(tx)
        else:
            raise Exception('Not connected')

    @control_rpc_call
    def sendrawtransaction(self, tx):
        if self.open():
            return self.proxy.sendrawtransaction(tx)
        else:
            raise Exception('Not connected')
コード例 #32
0
class RpcClient:
    def __init__(self):
        # Lock for threads
        self.lock = threading.Lock()
        self.rpc_ip, self.rpc_port, self.rpc_user, self.rpc_passwd = readRPCfile(
        )
        rpc_url = "http://%s:%s@%s:%d" % (self.rpc_user, self.rpc_passwd,
                                          self.rpc_ip, self.rpc_port)
        try:
            self.lock.acquire()
            self.conn = AuthServiceProxy(rpc_url, timeout=120)
        except JSONRPCException as e:
            err_msg = 'remote or local PIVX-cli running?'
            printException(getCallerName(), getFunctionName(), err_msg, e)
        except Exception as e:
            err_msg = 'remote or local PIVX-cli running?'
            printException(getCallerName(), getFunctionName(), err_msg, e)
        finally:
            self.lock.release()

    def decodeRawTransaction(self, rawTx):
        try:
            self.lock.acquire()
            res = self.conn.decoderawtransaction(rawTx)
        except Exception as e:
            err_msg = 'error in decodeRawTransaction'
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            res = None
        finally:
            self.lock.release()

        return res

    def getAddressUtxos(self, addresses):
        try:
            self.lock.acquire()
            res = self.conn.getaddressutxos({'addresses': addresses})
        except Exception as e:
            err_msg = "error in getAddressUtxos"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            res = None
        finally:
            self.lock.release()

        return res

    def getBlockCount(self):
        try:
            self.lock.acquire()
            n = self.conn.getblockcount()
        except Exception as e:
            err_msg = 'remote or local PIVX-cli running?'
            if str(e.args[0]) != "Request-sent":
                printException(getCallerName(), getFunctionName(), err_msg,
                               e.args)
            n = 0
        finally:
            self.lock.release()

        return n

    def getBlockHash(self, blockNum):
        try:
            self.lock.acquire()
            h = self.conn.getblockhash(blockNum)
        except Exception as e:
            err_msg = 'remote or local PIVX-cli running?'
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            h = None
        finally:
            self.lock.release()

        return h

    def getBudgetVotes(self, proposal):
        try:
            self.lock.acquire()
            votes = self.conn.getbudgetvotes(proposal)
        except Exception as e:
            err_msg = 'remote or local PIVX-cli running?'
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            votes = {}
        finally:
            self.lock.release()

        return votes

    def getFeePerKb(self):
        try:
            self.lock.acquire()
            # get transaction data from last 200 blocks
            feePerKb = float(self.conn.getfeeinfo(200)['feeperkb'])
            res = (feePerKb if feePerKb > MINIMUM_FEE else MINIMUM_FEE)
        except Exception as e:
            err_msg = 'error in getFeePerKb'
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            res = MINIMUM_FEE
        finally:
            self.lock.release()

        return res

    def getMNStatus(self, address):
        try:
            self.lock.acquire()
            mnStatusList = self.conn.listmasternodes(address)
            if not mnStatusList:
                return None
            mnStatus = mnStatusList[0]
            mnStatus['mnCount'] = self.conn.getmasternodecount()['enabled']
        except Exception as e:
            err_msg = "error in getMNStatus"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            mnStatus = None
        finally:
            self.lock.release()

        return mnStatus

    def getMasternodeCount(self):
        try:
            self.lock.acquire()
            ans = self.conn.getmasternodecount()
        except Exception as e:
            err_msg = "error in getMasternodeCount"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            ans = None
        finally:
            self.lock.release()

        return ans

    def getMasternodes(self):
        mnList = {}
        mnList['last_update'] = now()
        score = []
        try:
            self.lock.acquire()
            masternodes = self.conn.listmasternodes()
        except Exception as e:
            err_msg = "error in getMasternodes"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            masternodes = []
        finally:
            self.lock.release()

        for mn in masternodes:

            if mn.get('status') == 'ENABLED':
                if mn.get('lastpaid') == 0:
                    mn['score'] = mn.get('activetime')
                else:
                    lastpaid_ago = now() - mn.get('lastpaid')
                    mn['score'] = min(lastpaid_ago, mn.get('activetime'))

            else:
                mn['score'] = 0

            score.append(mn)

        score.sort(key=lambda x: x['score'], reverse=True)

        for mn in masternodes:
            mn['queue_pos'] = score.index(mn)

        mnList['masternodes'] = masternodes

        return mnList

    def getNextSuperBlock(self):
        try:
            self.lock.acquire()
            n = self.conn.getnextsuperblock()
        except Exception as e:
            err_msg = 'remote or local PIVX-cli running?'
            if str(e.args[0]) != "Request-sent":
                printException(getCallerName(), getFunctionName(), err_msg,
                               e.args)
            n = 0
        finally:
            self.lock.release()

        return n

    def getProposals(self):
        proposals = []
        try:
            self.lock.acquire()
            data = self.conn.getbudgetinfo()
        except Exception as e:
            err_msg = "error getting proposals"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            data = []
        finally:
            self.lock.release()

        for p in data:
            new_proposal = Proposal(p.get('Name'), p.get('URL'), p.get('Hash'),
                                    p.get('FeeHash'), p.get('BlockStart'),
                                    p.get('BlockEnd'),
                                    p.get('TotalPaymentCount'),
                                    p.get('RemainingPaymentCount'),
                                    p.get('PaymentAddress'), p.get('Yeas'),
                                    p.get('Nays'), p.get('Abstains'),
                                    float(p.get('TotalPayment')),
                                    float(p.get('MonthlyPayment')))
            proposals.append(new_proposal)

        return proposals

    def getProposalsProjection(self):
        proposals = []
        try:
            self.lock.acquire()
            data = self.conn.getbudgetprojection()
        except Exception as e:
            err_msg = "error getting proposals projection"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            data = []
        finally:
            self.lock.release()

        for p in data:
            new_proposal = Proposal(p.get('Name'), p.get('URL'), p.get('Hash'),
                                    p.get('FeeHash'), p.get('BlockStart'),
                                    p.get('BlockEnd'),
                                    p.get('TotalPaymentCount'),
                                    p.get('RemainingPaymentCount'),
                                    p.get('PaymentAddress'), p.get('Yeas'),
                                    p.get('Nays'), p.get('Abstains'),
                                    p.get('TotalPayment'),
                                    p.get('MonthlyPayment'))
            new_proposal = {}
            new_proposal['Name'] = p.get('Name')
            new_proposal['Allotted'] = float(p.get("Alloted"))
            new_proposal['Votes'] = p.get('Yeas') - p.get('Nays')
            new_proposal['Total_Allotted'] = float(p.get('TotalBudgetAlloted'))
            proposals.append(new_proposal)

        return proposals

    def getProtocolVersion(self):
        try:
            self.lock.acquire()
            prot_version = self.conn.getinfo().get('protocolversion')
            res = int(prot_version)
        except Exception as e:
            err_msg = 'error in getProtocolVersion'
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            res = DEFAULT_PROTOCOL_VERSION
        finally:
            self.lock.release()

        return res

    def getRawTransaction(self, txid):
        try:
            self.lock.acquire()
            res = self.conn.getrawtransaction(txid)
        except Exception as e:
            err_msg = "is Blockchain synced?"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            res = None
        finally:
            self.lock.release()

        return res

    def getStatus(self):
        status = False
        statusMess = "Unable to connect to a PIVX RPC server.\n"
        statusMess += "Either the local PIVX wallet is not open, or the remote RPC server is not responding."
        n = 0
        try:
            self.lock.acquire()
            n = self.conn.getblockcount()
            if n > 0:
                status = True
                statusMess = "Connected to PIVX RPC client"

        except Exception as e:
            # If loading block index set lastBlock=1
            if str(e.args[0]) == "Loading block index..." or str(
                    e.args[0]) == "Verifying blocks...":
                printDbg(str(e.args[0]))
                statusMess = "PIVX wallet is connected but still synchronizing / verifying blocks"
                n = 1
            elif str(e.args[0]) != "Request-sent" and str(
                    e.args[0]) != "10061":
                err_msg = "Error while contacting RPC server"
                printException(getCallerName(), getFunctionName(), err_msg,
                               e.args)

        finally:
            self.lock.release()

        return status, statusMess, n

    def isBlockchainSynced(self):
        try:
            self.lock.acquire()
            res = self.conn.mnsync('status').get("IsBlockchainSynced")
        except Exception as e:
            if str(e.args[0]) != "Request-sent":
                err_msg = "error in isBlockchainSynced"
                printException(getCallerName(), getFunctionName(), err_msg,
                               e.args)
            res = False
        finally:
            self.lock.release()

        return res

    def mnBudgetRawVote(self, mn_tx_hash, mn_tx_index, proposal_hash, vote,
                        time, vote_sig):
        try:
            self.lock.acquire()
            res = self.conn.mnbudgetrawvote(mn_tx_hash, mn_tx_index,
                                            proposal_hash, vote, time,
                                            vote_sig)
        except Exception as e:
            err_msg = "error in mnBudgetRawVote"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            res = None
        finally:
            self.lock.release()

        return res

    def decodemasternodebroadcast(self, work):
        try:
            self.lock.acquire()
            res = self.conn.decodemasternodebroadcast(work.strip())
        except Exception as e:
            err_msg = "error in decodemasternodebroadcast"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            res = ""
        finally:
            self.lock.release()

        return res

    def relaymasternodebroadcast(self, work):
        try:
            self.lock.acquire()
            res = self.conn.relaymasternodebroadcast(work.strip())
        except Exception as e:
            err_msg = "error in relaymasternodebroadcast"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            res = ""
        finally:
            self.lock.release()

        return res

    def sendRawTransaction(self, tx_hex, use_swiftx):
        try:
            self.lock.acquire()
            tx_id = self.conn.sendrawtransaction(tx_hex, True,
                                                 bool(use_swiftx))
        except Exception as e:
            err_msg = 'error in rpcClient.sendRawTransaction'
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            tx_id = None
        finally:
            self.lock.release()

        return tx_id

    def verifyMessage(self, pivxaddress, signature, message):
        try:
            self.lock.acquire()
            res = self.conn.verifymessage(pivxaddress, signature, message)
        except Exception as e:
            err_msg = "error in verifyMessage"
            printException(getCallerName(), getFunctionName(), err_msg, e.args)
            res = False
        finally:
            self.lock.release()

        return res
コード例 #33
0
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException

CSVFiles = "D:\BTC CSV"

rpc_connection = AuthServiceProxy("http://%s:%[email protected]:8332"%("username", "password"))
blockCount = rpc_connection.getblockcount()
for i in range(100000, 100100):#blockCount):
    currentHash = rpc_connection.getblockhash(i)
    currentBlock = rpc_connection.getblock(currentHash)
    currentTime = currentBlock['time']
    for transaction in currentBlock['tx']:
        txInfo = rpc_connection.getrawtransaction(transaction)
        txDecoded = rpc_connection.decoderawtransaction(txInfo)
        processed = [txDecoded['txid'], currentTime, txDecoded['weight']]
        for output in txDecoded['vout']:
            processed.append(str(output['value']))
        print("Processed: " + str(processed))
    print("Done with block " + str(i))
コード例 #34
0
class CoinbaseTxData(object):
    def __init__(self):
        # rpc_user and rpc_password are set in the bitcoin.conf file
        rpc_user = "******"
        rpc_password = "******"
        self.rpc_connection = AuthServiceProxy("http://%s:%[email protected]:8332" %
                                               (rpc_user, rpc_password))

        dir_path = os.path.dirname(os.path.realpath(__file__))
        self.data_root_path = dir_path + '/EmpiricalData'
        if not os.path.exists(self.data_root_path):
            os.makedirs(self.data_root_path)

    def extract_coinbase_data(self, block_height):

        block_hash = self.rpc_connection.getblockhash(block_height)
        block = self.rpc_connection.getblock(block_hash)
        txs = block["tx"]

        if block_height > 0:
            raw_coinbase_tx = self.rpc_connection.getrawtransaction(txs[0])
            coinbase_tx = self.rpc_connection.decoderawtransaction(
                raw_coinbase_tx)

        # coinbase_tx for genesis block is not retrievable via rpc
        elif block_height == 0:
            coinbase_tx = {
                "txid":
                "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
                "version":
                1,
                "locktime":
                0,
                "vin": [{
                    "coinbase":
                    "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73",
                    "sequence": 4294967295
                }],
                "vout": [{
                    "value": 50.00000000,
                    "n": 0,
                    "scriptPubKey": {
                        "asm":
                        "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f OP_CHECKSIG",
                        "hex":
                        "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac",
                        "reqSigs": 1,
                        "type": "pubkey",
                        "addresses": ["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"]
                    }
                }]
            }

        return coinbase_tx["vin"][0]["coinbase"].decode("hex")

    def save_coinbase_tx_data(self):

        # Check if data has already been saved
        try:
            self.load_coinbase_tx_data()
            coinbase_data = self.df['coinbase_tx_data'].tolist()
            start = len(coinbase_data)
        # Could not load data
        except (IOError):
            start = 0
            coinbase_data = []

        max_block_height = self.rpc_connection.getblockcount()

        # for i in range(start, max_block_height):
        for i in range(start, start + 300):
            try:
                coinbase_data.append([self.extract_coinbase_data(i)])
            except (JSONRPCException):
                print("Could not find coinbase transaction for block %i" % (i))
                coinbase_data.append([None])

        df = pd.DataFrame(coinbase_data)
        df.to_csv(self.data_root_path + "/coinbase_tx_data.txt")

    def load_coinbase_tx_data(self):

        self.df = pd.read_csv(self.data_root_path + "/coinbase_tx_data.txt")
        self.df.columns = ["block_height", "coinbase_tx_data"]

    def scrape_db_for_matches(self, pools):

        pool_strings = set(pools.values())
        pool_counts = pools
        for pool_name in pools.keys():
            pool_counts[pool_name] = 0

        self.load_coinbase_tx_data()

        for string in self.df['coinbase_tx_data']:
            for target in pool_strings:
                try:
                    match = re.search(target, string)
                    if match:
                        for pool_name in pools.keys():
                            if pools[pool_name] == target:
                                pool_counts[pool_name] += 1
                # No identifying string for pool
                except (TypeError):
                    pass

        return pool_counts
コード例 #35
0
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
alice_secret_atomic_swap = "thisIsASecretPassword123".encode('utf-8')
print("Alice's secret is: ", alice_secret_atomic_swap)
print("length of Alice's secret is: ", len(alice_secret_atomic_swap))




# rpc_user and rpc_password are set in the bitcoin.conf file
rpc_connection = AuthServiceProxy("http://%s:%[email protected]:18332"%('abel', 'abel'))
tx_alice_id = '394cb59fedc3f2a14aeb667416bb1844ebbd0ce5658db8d99c0f4ce7505143c4'
raw = rpc_connection.getrawtransaction(tx_alice_id)
print(raw)

decode_tx = rpc_connection.decoderawtransaction(raw)
print(decode_tx)

# print(rpc_connection.getaccount('n4mNGWL1ycLk45xgvEEn8V2uKbnpa7wr93')) #
# best_block_hash = rpc_connection.getbestblockhash()
# print(rpc_connection.getblock(best_block_hash))
#
# batch support : print timestamps of blocks 0 to 99 in 2 RPC round-trips:
# commands = [ [ "getblockhash", height] for height in range(100) ]
# block_hashes = rpc_connection.batch_(commands)
# blocks = rpc_connection.batch_([ [ "getblock", h ] for h in block_hashes ])
# block_times = [ block["time"] for block in blocks ]
# print(block_times)


# block_hash: '0000000093d5f3e8f846c86f85a1a038fd58299d0cb2dc62594c8cb74072901c'
# block_height: 1612350
コード例 #36
0
ファイル: views.py プロジェクト: rapierce/btc_blockbot-Web
def block_explorer(request):
    with open(r'static/keys/tokens.txt', 'r') as keys_File:
        keys = [line.rstrip('\n') for line in keys_File]

    # Get BlockBot Login Info
    rpc_user = keys[1]
    rpc_password = keys[2]
    block_Value = 0

    # rpc_user and rpc_password are set in the bitcoin.conf file
    rpc_connection = AuthServiceProxy("http://%s:%[email protected]:8332" %
                                      (rpc_user, rpc_password))

    request.method == 'GET'
    get_Block_Hash = (request.GET['get_Block'])

    # Pulling information from the Blockchain
    # get_Block_Hash = rpc_connection.getblockhash(block_Num)
    block_Hash = rpc_connection.getblock(get_Block_Hash)
    block_Num = block_Hash['height']
    transactions = block_Hash['tx']
    trans_Dict = {}
    trans_Dict['key'] = []
    block_Value = 0
    ts = block_Hash['time']
    time_Convert = datetime.utcfromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
    coinbase = 'Coinbase'
    address_Dict = {}
    address_Dict['trx'] = []

    for txid in transactions:

        #address_Dict['Transaction'] = []
        temp_Address_Dict = {}
        temp_Address_Dict[txid] = []
        tx_Value = 0
        raw_Tx = rpc_connection.getrawtransaction(txid)
        decoded_Tx = rpc_connection.decoderawtransaction(raw_Tx)
        segwit_Test = raw_Tx[8:10]
        # If segwit transaction it adds the appropriate flag (True) to the transaction
        #   ensuring it will be processed as a segwit transaction
        # Adds the transaction out values to the total block value
        if segwit_Test != '00':
            trans_Dict['key'].append(decoded_Tx)
            for output in decoded_Tx['vout']:
                tx_Value = tx_Value + output['value']

                if output['value'] > 0:
                    scriptPubKey_Data = (output['scriptPubKey'])
                    script_Dict = {'scriptPubKey': scriptPubKey_Data}
                    for script_Key, script_Value in script_Dict.items():
                        if script_Value['addresses']:
                            for adds in script_Value['addresses']:
                                #print (adds)
                                temp_Address_Dict.get(txid).append(adds)
            block_Value = block_Value + tx_Value
        else:
            flag = True
            segwit_Tx = rpc_connection.decoderawtransaction(raw_Tx, flag)
            trans_Dict['key'].append(segwit_Tx)
            for output in segwit_Tx['vout']:
                tx_Value = tx_Value + output['value']

                if output['value'] > 0:
                    scriptPubKey_Data = (output['scriptPubKey'])
                    script_Dict = {'scriptPubKey': scriptPubKey_Data}
                    for script_Key, script_Value in script_Dict.items():
                        if script_Value['addresses']:
                            for adds in script_Value['addresses']:
                                #print (adds)
                                temp_Address_Dict.get(txid).append(adds)
            block_Value = block_Value + tx_Value

        address_Dict.get('trx').append(temp_Address_Dict)

    print(address_Dict)

    return render(
        request, 'crypto/block_explorer.html', {
            'block_Num': block_Num,
            'block_Hash': block_Hash,
            'block_Value': block_Value,
            'trans_Dict': trans_Dict,
            'time_Convert': time_Convert,
            'address_Dict': address_Dict,
            'coinbase': coinbase
        })
コード例 #37
0
class LocalBlockchainRPCReader(BlockExplorerReader):

    rpc_connection              = None
    #transaction_output_cache    = None ''' deprecated '''

    def __init__(self, database_connector = None):
        BlockExplorerReader.__init__(self, database_connector) #super

        self.rpc_connection = AuthServiceProxy(
            "http://%s:%s@%s:%s" % (self.config.RPC_USERNAME,
                                    self.config.RPC_PASSWORD,
                                    self.config.RPC_HOST,
                                    self.config.RPC_PORT))

    def get_current_blockchain_block_height(self):
        return self.rpc_connection.getblockcount() #TODO: Error checking? - This should already be an integer.

    #Retreives a list of transactions at specified block height. Each tx
    #   will be formatted as a BCI-like tuple per
    #   get_bci_like_tuple_for_tx_id().
    #param0: block_height: Height at which to get a list of txs for.
    #param1: use_tx_out_addr_cache_only (Optional): When looking up addresses
    #   for previous transactions, ONLY refer to cache in SQLite database,
    #   rather than slower option of using RPC interface. If set to True,
    #   process will sleep until the data is available in the cache. Default:
    #   False.
    def get_tx_list(self, block_height, use_tx_out_addr_cache_only = False):
        ids = self.get_tx_ids_at_height(block_height)

        txs = []
        for tx_id in ids:
            bci_like_tuple = self.get_bci_like_tuple_for_tx_id(
                tx_id, use_tx_out_addr_cache_only)
            txs.append(bci_like_tuple)
        return txs

    #Checks if the specified transaction is the first time the specified address
    #   has received funds. If it is, it will cache this for the specified
    #   block height in the database so subsequent lookups will answer
    #   correctly. IMPORTANT: This function assumes that that blocks are being
    #   processed in a complete, monotonically-increasing fashion from the
    #   genesis block. Otherwise, correct results not guaranteed! It is the
    #   caller's responsibility to ensure that enough blocks have been
    #   processed.
    def is_first_transaction_for_address(self, addr, tx_id, block_height,
                                         benchmarker = None):
        if self.database_connector.has_address_been_seen_cache_if_not(addr,
                                                                      block_height):
            dprint("Address %s at block height %d was already seen." %
                (addr, block_height))
            return False
        else:
            dprint("Address %s at block height %d has no prior tx history." %
                  (addr, block_height))
            return True

    def get_block_hash_at_height(self, block_height):
        return self.rpc_connection.getblockhash(block_height)

    def get_tx_json_for_block_hash(self, block_hash):
        return self.rpc_connection.getblock(block_hash)

    def get_tx_ids_at_height(self, block_height):
        block_hash = self.get_block_hash_at_height(block_height)
        tx_json = self.get_tx_json_for_block_hash(block_hash)
        tx_ids = []
        for tx_id in tx_json['tx']:
            tx_ids.append(tx_id)
        return tx_ids

    #Returns the transaction in raw format. If the requested transaction is
    #   the sole transaction of the genesis block, bitcoind's RPC interface
    #   will throw an error 'No information available about transaction
    #   (code -5)' so we preempt this by raising a custom error that callers
    #   should handle; iterating callers should just move onto the next tx.
    #throws: NoDataAvailableForGenesisBlockError
    def get_raw_tx(self, tx_id):
        if tx_id == ('4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7af'
                     'deda33b'):
            raise custom_errors.NoDataAvailableForGenesisBlockError()
        else:
            return self.rpc_connection.getrawtransaction(tx_id)

    #Gets a human-readable string of the transaction in JSON format.
    def get_decoded_tx(self, tx_id):
        try:
            return self.rpc_connection.decoderawtransaction(
                self.get_raw_tx(tx_id))
        except custom_errors.NoDataAvailableForGenesisBlockError:
            #bitcoind won't generate this, but here's what it would look like
            genesis_json = {
                'txid':    ('4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2'
                            '127b7afdeda33b'),
                'version':  1,
                'locktime': 0,
                'vin': [{
                    "sequence":4294967295,
                    'coinbase': ('04ffff001d0104455468652054696d65732030332f4a6'
                                 '16e2f32303039204368616e63656c6c6f72206f6e2062'
                                 '72696e6b206f66207365636f6e64206261696c6f75742'
                                 '0666f722062616e6b73')
                }],
                'vout': [
                    {
                        'value': 50.00000000,
                        'n': 0,
                        'scriptPubKey': {
                            'asm': ('04678afdb0fe5548271967f1a67130b7105cd6a828'
                                    'e03909a67962e0ea1f61deb649f6bc3f4cef38c4f3'
                                    '5504e51ec112de5c384df7ba0b8d578a4c702b6bf1'
                                    '1d5f OP_CHECKSIG'),
                            'hex': ('4104678afdb0fe5548271967f1a67130b7105cd6a8'
                                    '28e03909a67962e0ea1f61deb649f6bc3f4cef38c4'
                                    'f35504e51ec112de5c384df7ba0b8d578a4c702b6b'
                                    'f11d5fac'),
                            'reqSigs': 1,
                            'type': 'pubkey',
                            'addresses': ['1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa']
                        }
                    }
                ]
            }
            return genesis_json

    #Converts required infromation from local bitcoind RPC into a format similar
    #   to that returned by Blockchain.info's API. This helps to make the code
    #   more agnostic as to the source of blockchain data.
    #Note: When an output address cannot be decoded, BCI excludes the "addr"
    #   field from the JSON returned. Therefore, this function will do the same.
    #   See:
    #   https://blockchain.info/tx/cee16a9b222f636cd27d734da0a131cee5dd7a1d09cb5f14f4d1330b22aaa38e
    #Note: When a previous output address for an input cannot be decoded, BCI
    #   excludes the "addr" field from the JSON returned. Therefore, this
    #   function will do the same. See:
    #   https://blockchain.info/tx/8ebe1df6ebf008f7ec42ccd022478c9afaec3ca0444322243b745aa2e317c272
    #param0: tx_id: Specified transaction hash
    #param1: use_tx_out_addr_cache_only (Optional): When looking up addresses
    #   for previous transactions, ONLY refer to cache in SQLite database,
    #   rather than slower option of using RPC interface. If set to True,
    #   process will sleep until the data is available in the cache. Default:
    #   False.
    def get_bci_like_tuple_for_tx_id(self, tx_id,
                                     use_tx_out_addr_cache_only = False):
        json_tuple = {}
        json_tuple['hash'] = tx_id
        json_tuple['inputs'] = []
        json_tuple['out'] = []

        subscription = None
        if use_tx_out_addr_cache_only:
            subscription = data_subscription.TxOutputAddressCacheSubscriber(
                database = self.database_connector)

        tx_json = self.get_decoded_tx(tx_id)

        #populate input addresses
        for vin in tx_json['vin']:
            #look up address based on its previous transaction
            prev_txid = None
            if 'txid' in vin:
                prev_txid = vin['txid']
            prev_vout = None
            if 'vout' in vin:
                prev_vout_num = vin['vout'] #yes, this RPC field is poorly named
                prev_out = {'n': prev_vout_num}
                try:
                    if use_tx_out_addr_cache_only:
                        #flag specifies that we will wait for cache to catch up
                        #   before continuing this operation. Process/thread
                        #   will sleep until then.
                        subscription.next_tx_id_needed = prev_txid
                        subscription.next_prev_tx_ouput_pos_needed = prev_vout_num
                        dprint(("get_bci_like_tuple_for_tx_id: May sleep until "
                                "tx output address is cached..."))
                        subscription.do_sleep_until_producers_ready()

                    address = self.get_output_address(prev_txid, prev_vout_num)
                    prev_out['addr'] = address
                except custom_errors.PrevOutAddressCannotBeDecodedError:
                    pass
                current_input = {'prev_out': prev_out}
                json_tuple['inputs'].append(current_input)
            else:
                #If there's no index specifying the txo from prev tx, there's
                #   probably nothing to do here. Should only come up for
                #   coinbase transactions.
                continue

        #populate output addresses
        for vout in tx_json['vout']:
            output_index = vout['n']
            current_output = {'n':output_index}
            if 'scriptPubKey' in vout and 'addresses' in vout['scriptPubKey']:
                address = vout['scriptPubKey']['addresses'][0]
                current_output['addr'] = address
            json_tuple['out'].append(current_output)

        return json_tuple

    #Returns an ordered list of output addresses for the specified transaction
    #   JSON as returned by the bitcoind RPC interface. If an address cannot be
    #   decoded for one of the outputs, a value of None will be inserted
    #   at that position in the list.
    #TODO: This does not properly handle multisig outputs that list multiple
    #   addresses per output. See:
    #   http://bitcoin.stackexchange.com/questions/4687/can-a-scriptpubkey-have-multiple-addresses
    #   When support for this is added, make sure to add a test case.
    def get_output_addresses(self, tx_json):
        assert 'vout' in tx_json
        output_addresses = []
        for vout in tx_json['vout']:
            assert 'scriptPubKey' in vout
            if 'addresses' in vout['scriptPubKey']:
                ouput_address = vout['scriptPubKey']['addresses'][0]
                output_addresses.append(ouput_address)
            else:
                output_addresses.append(None)
        return output_addresses

    #Raises: custom_errors.PrevOutAddressCannotBeDecoded
    #TODO: This does not properly handle multisig outputs that list multiple
    #   addresses per output.
    def get_output_address(self, tx_id, output_index, tx_json = None):
        if USE_TX_OUTPUT_ADDR_CACHE_FIRST:
            addr = self.database_connector.get_output_address(tx_id,
                                                              output_index)
            if addr is not None:
                return addr

        #not in cache, fall back to querying RPC interface
        if tx_json is None:
            tx_json = self.get_decoded_tx(tx_id)

        if 'vout' in tx_json and len(tx_json['vout']) > output_index and \
                'scriptPubKey' in tx_json['vout'][output_index]:
            if 'addresses' not in tx_json['vout'][output_index]['scriptPubKey']:
                raise custom_errors.PrevOutAddressCannotBeDecodedError
            else:
                return tx_json['vout'][output_index]['scriptPubKey'][
                    'addresses'][0]
        else:
            msg = ("Missing element for vout in get_output_address() with tx "
                   "id %s and output index %d") % (tx_id, output_index)
            logger.log_and_die(msg)
コード例 #38
0
ファイル: raw.py プロジェクト: iYalovoy/rawtransactiondemo

tx = rpc.createrawtransaction([{"txid": txid, "vout": vout}], \
                              {change_address: change_amount, \
                               dummy_address: SATOSHI})

# Pattern to replace
# Represents length of script, then OP_DUP OP_HASH160,
# then length of hash, then 20 bytes of zeros, OP_EQUALVERIFY OP_CHECKSIG
oldScriptPubKey = "1976a914000000000000000000000000000000000000000088ac"

# Data to insert
data = "Melons."
if len(data) > 75:
    raise Exception("Can't contain this much data-use OP_PUSHDATA1")

newScriptPubKey = "6a" + hexlify(chr(len(data))) + hexlify(data)

#Append int of length to start
newScriptPubKey = hexlify(chr(len(unhexlify(newScriptPubKey)))) + newScriptPubKey


if oldScriptPubKey not in tx:
    raise Exception("Something broke!")

tx = tx.replace(oldScriptPubKey, newScriptPubKey)

rpc.decoderawtransaction(tx)
tx = rpc.signrawtransaction(tx)['hex']
rpc.sendrawtransaction(tx)