예제 #1
0
class BitcoinService:
    def __init__(self):
        self.access = AuthServiceProxy("http://*****:*****@[email protected]:8332")

    def getInfo(self):
        return self.access.getinfo()
        
    def getlistreceivedbyaddress(self, num):
        return self.access.listreceivedbyaddress(num)

    def getBalance(self):
        return self.access.getbalance()

    def isValidAddress(self, addr):
        return self.access.validateaddress(addr)

    def generateAddress(self):
        return self.access.getnewaddress()

    def getAccount(self, addr):
        return self.access.getaccount(addr)

    def getAccountAddr(self, account):
        return self.access.getaccountaddress(account)
    
    def getreceivedbyaddress(self, addr):
        return self.access.getreceivedbyaddress(addr)

    def sendtoaddress(self, addr, amount, comment=""):
        return self.acccess.sendtoaddress(addr, amount, comment)
예제 #2
0
class BtcWallet():
    """btc钱包"""
    BTC_BLOCK_API = 'https://blockchain.info/'

    def __init__(self, app=None, consul_client=None):
        if app and consul_client:
            self.init_consul(app, consul_client)

    def init_consul(self, app, consul_client):
        try:
            rpc_user = app.config.get('CONFIG_BITCOIND_RPC_USER')
            rpc_pwd = app.config.get('CONFIG_BITCOIND_RPC_PASSWORD')
            wallet_passphrase = app.config.get('CONFIG_BITCOIND_WALLET_PASSWORD')
            self.ipport = consul_client.getRandomOneAvailableServiceIpPort(ConsulServiceName.BTC_CLI)
            # s = "http://%s:%s@" % (self.user, self.pwd) + self.ipport
            # print(s)

            self.bitcoin_cli = AuthServiceProxy(
                "http://%s:%s@" % (rpc_user, rpc_pwd) + self.ipport, timeout=10)
            print("Succeed to connect to the BTC node")

        except Exception as e:
            print(str(e))
            print("Failed to connect to the BTC node")

    # 是否连接BTC节点
    def is_connected(self):
        try:
            if self.bitcoin_cli.getwalletinfo().get('walletversion'):
                return True
            return False
        except Exception as e:
            print(str(e))
            print("Failed to connect to the BTC node")

    # 节点是否同步
    def is_sync(self):
        ret = self.bitcoin_cli.getblockchaininfo()
        if ret.get('blocks') != ret.get("headers"):
            return False
        else:
            return True

    # btc地址是否有效
    def is_valid_address(self, coin_address):
        if coin_address is None or coin_address == '':
            return False
        else:
            ret = self.bitcoin_cli.validateaddress(coin_address).get('isvalid')
            print('账户检查结果:', ret)
            return ret

            # return self.bitcoin_cli.validateaddress(coin_address).get('isvalid')

    # 获取账户余额, 默认经过6个区块确认
    def get_balance(self, coin_address):

        transaction_lists = self.bitcoin_cli.listunspent(1, 99999999, [coin_address])
        print(transaction_lists)
        current_amount = 0
        for transaction_list in transaction_lists:
            amount = transaction_list.get('amount')
            amount = float(amount)
            current_amount += amount
        return current_amount

    def get_balance_by_account(self, account):
        try:
            ret = self.bitcoin_cli.getbalance(account)
            return ret
        except Exception as e:
            logging.error('get balance error:{}'.format(str(e)))
            return None


    def estimate_fee(self):
        try:
            fee = self.bitcoin_cli.estimatefee(6)
            return fee
        except Exception as e:
            logging.error('get fee error:{}'.format(str(e)))
            return None

    def create_account(self, stellar_account):
        # private = random_key()
        # address = pubtoaddr(privtopub(private))
        # print(address, private)
        # return address, private
        address = self.bitcoin_cli.getnewaddress(stellar_account)
        private_key = self.bitcoin_cli.dumpprivkey(address)
        return address, private_key

    def get_block_num(self):
        """获取最新区块数"""
        try:
            block_num = self.bitcoin_cli.getblockcount()
            return block_num
        except Exception as e:
            logging.error('Get btc node block number error:{}'.format(str(e)))
            return None


    def get_chain_info(self):
        ret = self.bitcoin_cli.getblockchaininfo()
        return ret

    def get_block_info(self, block_num):
        """获取区块的详细信息"""
        param = "block-height/{}?format=json".format(block_num)
        api_url = self.BTC_BLOCK_API + param
        # print(api_url)

        blocks = requests.get(api_url, timeout=500).json()
        # print(type(blocks))
        return blocks

    # 链外转帐,普通交易
    def payment(self, btc_base_account, address_to, amount):
        try:
            txid = self.bitcoin_cli.sendfrom(btc_base_account, address_to, amount)
            return True, txid
        except Exception as e:
            logging.error('btc payment error:{}'.format(str(e)))
            return False, str(e)

    def hash_get_detail(self, tx_id):
        """
        Arguments:
        1. "txid" (string, required) The transaction id
        """
        # 根据txid获取确认链外交易信息
        ret = self.bitcoin_cli.gettransaction(tx_id)
        abandoned = ret.get("details")[0].get("abandoned")  # 获取abandon信息
        confirmation_num = ret.get('confirmations')  # 获取确认数

        # 如果确认数小于1,则未确认
        if confirmation_num < 1:
            msg = dict(confirm=str(ret))
            # msg = ret.get("details")[0]
            return False, False, msg, None
        # 如果确认数大于1,则确认
        else:
            msg = dict(confirm=str(ret))
            # msg = ret
            fee = abs(ret.get("fee"))
            if abandoned:
                return True, False, msg, None
            else:
                return True, True, msg, fee

    def raw_payment(self, address_from, address_to, collect_amount):
        inputs = []
        # 获取地址余额信息
        try:
            unspend_lists = self.bitcoin_cli.listunspent(1, 9999999, [address_from])
            for unspend_list in unspend_lists:
                # if unspend_list.get('amount') <= 0:
                #     continue
                # else:
                txid = unspend_list.get('txid')
                vout = unspend_list.get('vout')
                inputs.append({'txid': txid, 'vout': vout})

            outputs = {address_to: round(collect_amount, 8)}

            # 交易建立和签名时不用连接比特币网络,只有在执行交易时才需要将交易发送到网络
            # 创建裸交易
            transaction_hash = self.bitcoin_cli.createrawtransaction(inputs, outputs)

            # 使用私钥签名,获取16进制信息
            hex = self.bitcoin_cli.signrawtransaction(transaction_hash).get('hex')

            # 广播到p2p网络,返回交易哈希
            trading_hash = self.bitcoin_cli.sendrawtransaction(hex, False)

            return True, trading_hash, ''
        except Exception as e:
            print(e)
            return None, None, ''

    def btc_transaction_record(self, block_num):
        # 获取某一区块信息
        block_info = self.get_block_info(block_num)
        blocks = block_info.get('blocks')
        txs = blocks[0].get('tx')
        records = []
        for tx in txs:
            outs = tx.get('out')
            hash = tx.get('hash')
            inputs = tx.get('inputs')
            p_out = inputs[0].get('prev_out')
            if not p_out:
                continue
            else:
                addr_from = p_out.get('addr')
            for out in outs:
                re = []
                addr_to = out.get('addr')
                value = out.get('value') / (10 ** 8)
                # addr_to与User表中绑定的地址进行对比,如果有,则说明此address_to有冲币记录
                user = User.address_query_user('BTC', addr_to)
                if not user:
                    continue
                else:
                    re.append(addr_from)
                    re.append(addr_to)
                    re.append(value)
                    re.append(hash)
                    records.append(re)
        return records

    def get_accounts(self, addr):
        try:
            ad = self.bitcoin_cli.getaccount(addr)
            return ad
        except Exception as e:
            # logging.error('get btc_account error:{}'.format(str(e)))
            return None

    def get_address_byaccount(self, account):
        re = self.bitcoin_cli.getaddressesbyaccount(account)

        return re

    def test1(self):

        transaction_list = self.bitcoin_cli.listaccounts()
        # transaction_list = self.bitcoin_cli.getwalletinfo()
        print(transaction_list)
예제 #3
0
파일: bitrpc.py 프로젝트: zjohnson24/Ember
# rpc_user and rpc_password are set in the bitcoin.conf file
access = AuthServiceProxy("http://*****:*****@127.0.0.1:10022/")

cmd = sys.argv[1].lower()

if cmd == "backupwallet":
    try:
        path = raw_input("Enter destination path/filename: ")
        print access.backupwallet(path)
    except:
        print "\n---An error occurred---\n"

elif cmd == "getaccount":
    try:
        addr = raw_input("Enter a Bitcoin address: ")
        print access.getaccount(addr)
    except:
        print "\n---An error occurred---\n"

elif cmd == "getaccountaddress":
    try:
        acct = raw_input("Enter an account name: ")
        print access.getaccountaddress(acct)
    except:
        print "\n---An error occurred---\n"

elif cmd == "getaddressesbyaccount":
    try:
        acct = raw_input("Enter an account name: ")
        print access.getaddressesbyaccount(acct)
    except:
예제 #4
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)
예제 #5
0
if (len(inputUser.strip()) > 0):
    logger.info(
        "Checking {} configuration for holding account address...".format(
            coinConfFileName))
    holdingAddressConfigName = holdingAddressPrefix + inputUser
    if holdingAddressConfigName in configBag:
        holdingWalletAddress = configBag[holdingAddressConfigName]
    else:
        logger.error(
            "Holding Address configuration '{}' is missing. Aborting.".format(
                holdingAddressConfigName))
        exit()

    logger.info(
        "Finding account for address {}...".format(holdingWalletAddress))
    holdingWalletName = rpcConnection.getaccount(holdingWalletAddress)
    if (holdingWalletName is not None):
        logger.info(
            "Cool {}, let's get started. This script will use {} as the holding wallet ({})."
            .format(inputUser, holdingWalletName, holdingWalletAddress))
    else:
        logger.error(
            "Failed to lookup account for user '{}'".format(inputUser))
else:
    logger.critical("Unrecognized user '{}'. Aborting.".format(inputUser))
    exit()

print()
logger.info("Processing all node accounts...")
walletAccounts = rpcConnection.listaccounts()
allUnspent = []