def handle(self, *args, **options):

        rpc = AuthServiceProxy('http://' + settings.BITCOIN_RPC_USERNAME + ':' + settings.BITCOIN_RPC_PASSWORD + '@' + settings.BITCOIN_RPC_IP + ':' + str(settings.BITCOIN_RPC_PORT))

        private_keys_imported = False

        for address in Address.objects.all():
            address_found = True
            try:
                rpc.dumpprivkey(address.address)
            except JSONRPCException as e:
                if e.code == -4:
                    # Address is not found
                    print 'Address ' + address.address + ' was not found. Importing it...'

                    # Do some key magic
                    new_address_full_path = address.wallet.path + [address.subpath_number]
                    new_address_full_path_str = '/'.join([str(i) for i in new_address_full_path])
                    key = Key.from_text(settings.MASTERWALLET_BIP32_KEY)
                    subkey = key.subkeys(new_address_full_path_str).next()

                    # Check address and form the private key
                    btc_address = subkey.address(use_uncompressed=False)
                    assert btc_address == address.address
                    btc_private_key = subkey.wif(use_uncompressed=False)

                    # Do the importing
                    rpc.importprivkey(btc_private_key, '', False)
                    private_keys_imported = True

        if private_keys_imported:
            print 'Note! Private keys were added, but they were not scanned! Please restart bitcoin with -rescan option!'
    def handle(self, *args, **options):

        rpc = AuthServiceProxy('http://' + settings.BITCOIN_RPC_USERNAME +
                               ':' + settings.BITCOIN_RPC_PASSWORD + '@' +
                               settings.BITCOIN_RPC_IP + ':' +
                               str(settings.BITCOIN_RPC_PORT))

        private_keys_imported = False

        for address in Address.objects.all():
            address_found = True
            try:
                rpc.dumpprivkey(address.address)
            except JSONRPCException as e:
                if e.code == -4:
                    # Address is not found
                    print 'Address ' + address.address + ' was not found. Importing it...'

                    # Do some key magic
                    new_address_full_path = address.wallet.path + [
                        address.subpath_number
                    ]
                    new_address_full_path_str = '/'.join(
                        [str(i) for i in new_address_full_path])
                    key = Key.from_text(settings.MASTERWALLET_BIP32_KEY)
                    subkey = key.subkeys(new_address_full_path_str).next()

                    # Check address and form the private key
                    btc_address = subkey.address(use_uncompressed=False)
                    assert btc_address == address.address
                    btc_private_key = subkey.wif(use_uncompressed=False)

                    # Do the importing
                    rpc.importprivkey(btc_private_key, '', False)
                    private_keys_imported = True

        if private_keys_imported:
            print 'Note! Private keys were added, but they were not scanned! Please restart bitcoin with -rescan option!'
Beispiel #3
0
def newaddress():
    # {"apiKey": "0000", "params": {"account":""}}
    result_data = "{'code':'%(code)s','data':%(data)s,'msg':'%(msg)s'}"
    rpc_connection = AuthServiceProxy("http://%s:%[email protected]:18332" %
                                      (rpc_user, rpc_password))

    try:
        form_data = request.json
        param = getParams(form_data, 'post')
        if param == None:
            raise Exception('入参异常')
        account = param['account']
        address_type = 'legacy'
        address = rpc_connection.getnewaddress(account, address_type)
        a = rpc_connection.walletpassphrase('admin', 30)
        address_pkey = rpc_connection.dumpprivkey(address)
        result_data = result_data % {
            "code": "0000",
            "data": str({
                'address': address,
                'address_pkey': address_pkey
            }),
            "msg": '0'
        }
        result_data = demjson.decode(result_data)
    except BaseException as err:

        err = str(err).replace("'", "")
        result_data = result_data % ({
            "code": "0001",
            "data": "0",
            "msg": str(err)
        })

        # print(result_data)
        result_data = demjson.decode(result_data)
        # batch support : print timestamps of blocks 0 to 99 in 2 RPC round-trips:
    return jsonify(result_data)
            '%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":
Beispiel #5
0
class Bitcoind:
	"""
	Connection to a Bitcoin daemon process.
	"""

	def __init__(self, settings):
		"""
		Arguments:
		settings: a settings object; must contain the attribute bitcoinRPCURL.

		Connects to a Bitcoin daemon process, indicated by settings.bitcoinRPCURL.
		If settings.bitcoinRPCURL is empty, this object will not be connected.
		"""

		if settings.bitcoinRPCURL != "":
			log.log("Making connection to Bitcoin daemon...")
			self.access = AuthServiceProxy(settings.bitcoinRPCURL)
			log.log("...done")
		else:
			log.log("Bitcoin-RPC URL is not set: not connecting")
			self.access = None


	def isConnected(self):
		"""
		Return value:
		bool

		Returns whether this object is connected.
		"""

		return self.access != None
		

	def getBalance(self):
		"""
		Return value:
		int, in Satoshi

		Returns the balance.
		"""

		return self.DecimaltoAmount(self.access.getbalance())


	def getBlockCount(self):
		"""
		Return value:
		int

		Returns the block count.
		"""

		return self.access.getblockcount()


	def getPrivateKey(self, address):
		"""
		Arguments:
		address: str, Base58Check-encoded address
		Return value:
		str, Base58Check-encoded private key

		Returns the private key corresponding to the given address.
		"""

		return self.access.dumpprivkey(address)


	def getTransactionHashesByBlockHeight(self, height):
		"""
		Arguments:
		height: int
		Return value:
		list of str, hexadecimal, Bitcoin hash byte order

		Returns the transaction hashes in the block (in the main chain) at the
		given height.
		"""

		bhash = self.access.getblockhash(height)
		block = self.access.getblock(bhash)
		return block["tx"]


	def getTransaction(self, thash):
		"""
		Arguments:
		thash: str, hexadecimal, Bitcoin hash byte order

		Return value:
		dict, containing:
			vin: list of dict, each element containing:
				coinbase [only for coinbase transactions]
				txid [only for non-coinbase transactions]:
					str, hexadecimal, Bitcoin hash byte order
					hash of input transaction

		Returns information about the transaction indicated by the given hash.
		"""

		return self.access.getrawtransaction(thash, 1)


	def listUnspent(self):
		"""
		Return value:
		list of dict, each element containing:
			address: 
				str, Base58Check-encoded address
			amount:
				int, in Satoshi
			scriptPubKey:
				str, binary
			txid:
				str, binary, OpenSSL byte order
			vout:
				int

		Returns information about the available unspent transaction outputs.
		"""

		ret = self.access.listunspent()
		for vout in ret:
			vout["txid"] = binascii.unhexlify(vout["txid"])[::-1] #reversed; TODO: is this the right place?
			vout["scriptPubKey"] = binascii.unhexlify(vout["scriptPubKey"])
			vout["amount"] = self.DecimaltoAmount(vout["amount"])
		return ret


	def sendRawTransaction(self, txData):
		"""
		Arguments:
		txData: str, binary

		Send the given serialized transaction over the Bitcoin network.
		"""

		self.access.sendrawtransaction(txData.encode("hex"))


	def DecimaltoAmount(self, value):
		return int(value*100000000)
Beispiel #6
0
    return(addr_utxos)


# Lets find the UTXOs corresponding to P2SH address
p2sh_utxos = find_UTXOs_of_address(p2sh_addr)



# ***** Accept a P2PKH address to send the funds to

# Instead of using an existing P2PKH address I created a new one (for training reasons)

# Returns the address' Public Key
rec_addr_pubk = rpc_con.getnewaddress()
# Address' Private Key
rec_addr_privk = rpc_con.dumpprivkey(rec_addr_pubk)
# Secret key corresponding to the pubkey
rec_p2pkh_sk = PrivateKey(rec_addr_privk)
# Get the P2PKH address (from the public key)
rec_p2pkh_addr = rec_p2pkh_sk.get_public_key().get_address()



# ***** Calculate the appropriate fees with respect to the size of the transaction

# Didn't manage to connect to an on-line service to automatic calculate fees
# based on transaction's size. So I used an empirical formula to calculate
# transaction's size (in bytes) and then to calculate the total fees using an
# average fees per byte.
def calc_tx_fee(inputs, outputs, btcs_per_byte=50e-8):
    '''
Beispiel #7
0
def create_p2sh():
    '''
    This method creates a P2SH address containing a CHECKLOCKTIMEVERIFY plus
    a P2PKH locking funds with a key up to specific blockchain height
    
    Arguments:
        pubKey: public key for the P2PKH part of the redeem script
        lockBlocks: absolute lock (set to blockchain height)
    Returns:        
        lock_block_height: the specific blockchain height lock (in blocks)
        new_addr_privk: the private key of created P2SH address
        p2sh_addr: the new P2SH address
    '''

    # Setup the network
    setup('regtest')

    # Initialize proxy for RPC calls
    rpcuser = "******"
    rpcpassword = "******"
    rpc_con = AuthServiceProxy("http://%s:%[email protected]:18443" %
                               (rpcuser, rpcpassword))

    # ***** Accept a public (or optionally a private) key for the P2PKH part of
    #       the redeem script

    # Create a new Bitcoin Address (P2PKH)
    # Call the node's getnewaddress JSON-RPC method
    # Returns the address' Public Key
    new_addr_pubk = rpc_con.getnewaddress()

    # ***** Accept a future time expressed either in block height or in UNIX
    #       Epoch time

    # Numbers of blockchain height corresponding to absolute lock time
    lock_block_height = 103

    # Get the corresponding private key from the wallet
    # Call the node's dumpprivkey JSON-RPC method
    new_addr_privk = rpc_con.dumpprivkey(new_addr_pubk)

    # Get information about current blockchain height
    # Call the node's getblockcount JSON-RPC method
    current_block_height = rpc_con.getblockcount()
    if (lock_block_height < current_block_height):
        print(
            '\n***BEWARE*** Given lock (%d blocks) is lower than current blockchain height (%d blocks)'
            % (lock_block_height, current_block_height))
    else:
        print('Current blockchain height: %d blocks' % current_block_height)
        print('Fund\'s lock is set to: %d blocks' % lock_block_height)

    # Setting up an appropriate sequence to provide the script
    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, lock_block_height)

    # Secret key corresponding to the pubkey needed for the P2SH (P2PKH) transaction
    p2pkh_sk = PrivateKey(new_addr_privk)

    # Get the P2PKH address (from the public key)
    p2pkh_addr = p2pkh_sk.get_public_key().get_address()

    redeem_script = Script([
        seq.for_script(), 'OP_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP',
        'OP_HASH160',
        p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
    ])

    # Create a P2SH address from a redeem script
    p2sh_addr = P2shAddress.from_script(redeem_script)

    # VERY IMPORTANT: I must insert P2SH address into my wallet
    rpc_con.importaddress(p2sh_addr.to_address())

    # ***** Display the P2SH address
    print(
        '\nNewly created P2SH address with absolute lock set to %d blockchain height:'
        % lock_block_height)
    print(p2sh_addr.to_address())

    return (lock_block_height, new_addr_privk, p2sh_addr.to_address())
Beispiel #8
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)
Beispiel #9
0
random = "mrTRKLaDF86gLdKnacjxkXJdRFS6S8poTY"
txtorandom = "bdad390ea15f1828466266a97d4f219ff2e64111a60cb204b30148b199260bd0"
random2 = "mmQDjcub4ozy7e7ET6Yx75MDcLQHdhofbU"
#print "NEW", bitcoin.getnewaddress("")
#print bitcoin.validateaddress(mine)



print ""
print "Addresses and priv keys in entire wallet"
addresses = bitcoin.getaddressesbyaccount("")
print addresses
for add in addresses:
    if not add[0] == '2':
        print bitcoin.dumpprivkey(add), add



## Create a multi-sig

print ""
print "Multi sig address"
adds = [pubkeymine, pubkeymike]
print "Addresses used", adds
multi = bitcoin.addmultisigaddress(2, adds)
multi = bitcoin.createmultisig(2, adds)
print multi

"""
print ""
Beispiel #10
0
def vote(request, bid='0', v='0'):
    c = {'page_tag': "vote", 'now': now(), 'bid': bid, 'v': v}
    bet = Bet.objects.filter(id=bid)
    if len(bet) > 0:
        bet = bet[0]
        if v is not '0' and v is not '1':
            messages.add_message(request, messages.ERROR, "选项错误")
        else:
            if request.method == 'POST':
                post_address = request.POST['address'].strip()
                if post_address == '':
                    messages.add_message(request, messages.ERROR, "请输入地址")
                    return render(request, 'vote.html', c)
                    exit()
                paymentBackAddress = PaymentBackAddress.objects.filter(
                    address=post_address)
                if len(paymentBackAddress) == 0:
                    paymentBackAddress = PaymentBackAddress.objects.create(
                        address=post_address)
                else:
                    paymentBackAddress = paymentBackAddress[0]
                PaymentOptions = PaymentOption.objects.order_by('-id')
                if len(PaymentOptions) == 0:
                    return HttpResponse(json.dumps({'error': -402}))
                try:
                    rpc_connection = AuthServiceProxy(
                        "http://%s:%s@%s:%s" % (PaymentOptions[0].rpc_username,
                                                PaymentOptions[0].rpc_password,
                                                PaymentOptions[0].rpc_address,
                                                PaymentOptions[0].rpc_port))
                    address = rpc_connection.getnewaddress('Bet')
                    privkey = rpc_connection.dumpprivkey(address)
                    if address is not None and privkey is not None:
                        address = PaymentAddress.objects.create(
                            address=address, account='Bet', privkey=privkey)
                        BetLog.objects.create(bet=bet,
                                              option=(v == '1'),
                                              address=address,
                                              backAddress=paymentBackAddress)
                        address_qrcode = pyqrcode.create(address.address)
                        c = {
                            'page_tag':
                            "vote",
                            'now':
                            now(),
                            'bet':
                            bet,
                            'bid':
                            bid,
                            'v':
                            v,
                            'address':
                            address,
                            'address_qrcode':
                            'data:image/png;base64,' +
                            address_qrcode.png_as_base64_str(scale=4)
                        }
                    else:
                        return HttpResponse(json.dumps({'error': -404}))
                except Exception as ex:
                    print(ex)
                    return HttpResponse(json.dumps({'error': -403}))
    else:
        messages.add_message(request, messages.ERROR, "该竞猜不存在")

    return render(request, 'vote.html', c)
		prev_tx = sidechain.getrawtransaction(args.sidechainClaimTx, 1)
		prev_out = prev_tx["vout"][0]
		assert(prev_out["scriptPubKey"]["type"] == "withdrawout")
		prev_script = prev_out["scriptPubKey"]["asm"].split(" ")
		assert(prev_script[10] == "OP_NOP3")
		if "confirmations" not in prev_tx or prev_tx["confirmations"] < int(prev_script[9]):
			print("You must wait for at least %s confirmations to claim this output (have %d)" % (prev_script[9], prev_tx["confirmations"]))
			exit(1)

		p2sh_res = sidechain.createmultisig(1, [args.sidechainAddress])

		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]
Beispiel #12
0
class Bitcoind_Real:
    """
	Connection to a Bitcoin daemon process.
	"""
    def __init__(self, settings):
        """
		Arguments:
		settings: a settings object; must contain the attribute bitcoinRPCURL.

		Connects to a Bitcoin daemon process, indicated by settings.bitcoinRPCURL.
		If settings.bitcoinRPCURL is empty, this object will not be connected.
		"""

        if settings.bitcoinRPCURL != "":
            log.log("Making connection to Bitcoin daemon...")
            self.access = AuthServiceProxy(settings.bitcoinRPCURL)
            log.log("...done")
        else:
            log.log("Bitcoin-RPC URL is not set: not connecting")
            self.access = None

    def isConnected(self):
        """
		Return value:
		bool

		Returns whether this object is connected.
		"""

        if self.access is None:
            log.log(
                'Bitcoind access object does not exist (e.g. because the Bitcoin-RPC URL is incorrect)'
            )
            return False

        try:
            info = self.access.getinfo()
        except:
            log.log(
                'Bitcoind access object exists, but gives an error when executing a command:'
            )
            log.logException()
            return False

        log.log('Connected to bitcoind version %s' % info['version'])

        return True

    def getBalance(self):
        """
		Return value:
		int, in Satoshi

		Returns the balance.
		"""

        return self.DecimaltoAmount(self.access.getbalance())

    def getBlockCount(self):
        """
		Return value:
		int

		Returns the block count.
		"""

        return self.access.getblockcount()

    def getNewAddress(self):
        """
		Return value:
		str, Base58Check-encoded address

		Generates and returns a new address.
		"""
        return self.access.getnewaddress()

    def getPrivateKey(self, address):
        """
		Arguments:
		address: str, Base58Check-encoded address
		Return value:
		str, Base58Check-encoded private key

		Returns the private key corresponding to the given address.
		"""

        return self.access.dumpprivkey(address)

    def getBlockInfoByBlockHeight(self, height):
        """
		Arguments:
		height: int

		Return value:
		dict; containing:
			hash: str; the block hash (hexadecimal)
			merkleroot: str; the block Merkle root (hexadecimal, Bitcoin hash byte order)
			time: int; the block timestamp (UNIX time)

		Returns information about the block (in the main chain) at the
		given height.
		"""
        bhash = self.access.getblockhash(height)
        binfo = self.access.getblock(bhash)
        return \
        {
        "hash": binfo["hash"],
        "merkleroot": binfo["merkleroot"],
        "time": binfo["time"]
        }

    def getTransactionHashesByBlockHeight(self, height):
        """
		Arguments:
		height: int
		Return value:
		list of str, hexadecimal, Bitcoin hash byte order

		Returns the transaction hashes in the block (in the main chain) at the
		given height.
		"""

        bhash = self.access.getblockhash(height)
        block = self.access.getblock(bhash)
        return block["tx"]

    def getTransaction(self, thash):
        """
		Arguments:
		thash: str, hexadecimal, Bitcoin hash byte order

		Return value:
		dict, containing:
			vin: list of dict, each element containing:
				coinbase [only for coinbase transactions]
				txid [only for non-coinbase transactions]:
					str, hexadecimal, Bitcoin hash byte order
					hash of input transaction
			hex: str, hexadecimal, serialization of the transaction
			confirmations: int, number of confirmations

		Returns information about the transaction indicated by the given hash.
		"""

        return self.access.getrawtransaction(thash, 1)

    def importprivkey(self, privateKey, description, rescan):
        return self.access.importprivkey(privateKey, description, rescan)

    def listUnspent(self):
        """
		Return value:
		list of dict, each element containing:
			address: 
				str, Base58Check-encoded address
			amount:
				int, in Satoshi
			scriptPubKey:
				str, binary
			txid:
				str, binary, OpenSSL byte order
			vout:
				int

		Returns information about the available unspent transaction outputs.
		"""

        ret = self.access.listunspent()
        for vout in ret:
            vout["txid"] = binascii.unhexlify(
                vout["txid"])[::-1]  #reversed; TODO: is this the right place?
            vout["scriptPubKey"] = binascii.unhexlify(vout["scriptPubKey"])
            vout["amount"] = self.DecimaltoAmount(vout["amount"])
        return ret

    def sendRawTransaction(self, txData):
        """
		Arguments:
		txData: str, binary

		Send the given serialized transaction over the Bitcoin network.
		"""
        try:
            self.access.sendrawtransaction(txData.encode("hex"))
        except JSONRPCException as e:
            if e.error['code'] == RPC_TRANSACTION_ALREADY_IN_CHAIN:
                #It's perfectly fine (but very unlikely) that the transaction is
                #already in the block chain.
                #After all, we WANT it to end up in the block chain!
                pass
            else:
                raise

    def DecimaltoAmount(self, value):
        return int(value * 100000000)

    def handleMessage(self, msg):
        return \
        [
        messages.BitcoinReturnValue(
         value=msg.function(self),
         ID=msg.returnID, channelIndex=msg.returnChannelIndex)
        ]
Beispiel #13
0
            '%s %s -create in=%s:%d:%s:%d outaddr=%s:"%s"' %
            (sidechain_tx_path, "-testnet" if is_testnet == 1 else "",
             sys.argv[2], 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": sys.argv[2],
                "vout": 0,
                "scriptPubKey": prev_out["scriptPubKey"]["hex"],
                "redeemScript": p2sh_res["redeemScript"],
                "nValue": prev_out["serValue"]
            }], [sidechain.dumpprivkey(sys.argv[3])])
        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 sys.argv[1] == "send-to-mainchain":
        if len(sys.argv) != 4:
            help()

        p2sh_tx_test = bitcoin.decoderawtransaction(
Beispiel #14
0
class BitcoinClient(object):
    """Bitcoin client class"""

    # Handler for Bitcoin connection
    connection = None

    network_info = None
    blockchain_info = None
    wallet_info = None

    def __init__(self):
        self.user = os.environ["BITCOIN_USER"]
        self.password = os.environ["BITCOIN_PASSWORD"]
        self.host = os.environ["BITCOIN_HOST"]
        self.port = int(os.environ["BITCOIN_PORT"])

        self.connection = AuthServiceProxy(
            "http://%s:%s@%s:%i" %
            (self.user, self.password, self.host, self.port))

    def info(self):
        # Use following links for reference:
        # https://chainquery.com/bitcoin-api/getblockchaininfo
        # https://chainquery.com/bitcoin-api/getnetworkinfo
        # https://chainquery.com/bitcoin-api/getwalletinfo
        self.blockchain_info = self.connection.getblockchaininfo()
        self.network_info = self.connection.getnetworkinfo()
        self.wallet_info = self.connection.getwalletinfo()

        accounts = []
        for acc in self.connection.listaccounts(0):
            if len(acc) > 0:
                accounts.append(acc)

        # new_address = self.new_address()
        # new_address_valid = self.validate_address(new_address)
        # new_address_pk = self.get_private_key(new_address)

        # New address: "miC9oPat2xrtDstticmrw2YM7UUN9A6jcn"
        # New address private key: "cNci511KkyyU8GqMdZVxv1NxMbUMKqjo75PAQNdBFGgzbD7W8gZm"

        # valid_bitcoin_address = '134dV6U7gQ6wCFbfHUz2CMh6Dth72oGpgH'
        # addr = Address(self, valid_bitcoin_address)

        data_hash = {
            "blocks": int(self.blockchain_info["blocks"]),
            "headers": int(self.blockchain_info["headers"]),
            "bestblockhash": self.blockchain_info["bestblockhash"],
            "difficulty": float(self.blockchain_info["difficulty"]),
            "accounts": accounts,
            "account_addresses": self.connection.getaddressesbyaccount(""),
            # "new_address": str(self.new_account('Trololo')),
            # "new_address": new_address,
            # "new_address_valid": new_address_valid,
            # "new_address_pk": new_address_pk,
            # "valid_address_balance": addr.balance(),
        }
        return data_hash

    def balance(self):
        """Overall balance of current wallet

        Returns:
            (int) balance in satoshis

        """
        balance = float(self.connection.getbalance())
        # return balance
        return int(balance * SATOSHI)

    def new_address(self):
        """Generate new address"""
        return self.connection.getnewaddress()

    def get_private_key(self, address):
        """Fetch private key of specific address owned by you.

        Keyword arguments:
        address -- address (public key) to fetch from
        """
        return self.connection.dumpprivkey(address)

    def validate_address(self, address):
        """Check that address is valid on Blockchain.

        Keyword arguments:
        address -- address (public key) to validate
        """
        result = self.connection.validateaddress(address)
        if "isvalid" in result:
            return result["isvalid"]
        return False

    def new_account(self, name):
        """Generate new account and address.

        Keyword arguments:
        name -- name of the account, not stored in the blockchain
        """
        return self.connection.getnewaddress(name)

    def generate_blocks(self, amount):
        """Generate some blocks. Availabe only in Regtest mode.

        Keyword arguments:
        amount -- number of blocks to generate
        """
        return self.connection.generate(amount)

    def lock_wallet(self):
        """Lock current wallet."""
        return self.connection.walletlock()

    def unlock_wallet(self, passphrase=None, seconds=60):
        """Unlock current wallet with a passphase.

        Keyword arguments:
        passphrase -- the passphrase that unlocks the wallet
        seconds -- the number of seconds after which the decryption key will be automatically deleted from memory
        """
        if not passphrase:
            passphrase = os.environ["BITCOIN_WALLET_PASSPHRASE"]
        return self.connection.walletlock(passphrase, seconds)

    def change_wallet_passphrase(self,
                                 old_passphrase=None,
                                 new_passphrase=None):
        """Set passphrase for current wallet.

        Keyword arguments:
        old_passphrase -- old passphrase that unlocks the wallet
        new_passphrase -- new passphrase that unlocks the wallet
        """
        if not old_passphrase:
            old_passphrase = ''
        if not new_passphrase:
            new_passphrase = os.environ["BITCOIN_WALLET_PASSPHRASE"]
        return self.connection.walletpassphrasechange(old_passphrase,
                                                      new_passphrase)

    def send(self, from_addr, to_addr, amount):
        """Send funds from address to address. Returns transaction ID.

        Keyword arguments:
        from_addr -- address (public key) we're sending funds from
        to_addr -- address (public key) we're sending funds to
        amount -- (float) amount of bitcoins to send
        """
        return self.connection.sendfrom(from_addr, to_addr, amount)
bitcoin = AuthServiceProxy("http://%s:%[email protected]:8332"%(rpc_user, rpc_password))

add = dict()
privkey = dict()
pubkey = dict()
mid = "\",\"" #this thing inserts these 3 characters ","


for i in range(0, 3): #Generate three new addresses (Pub Key & Priv Key)
    print
    print "Brand New Address Pair: Number", i+1
    
    add[i] = bitcoin.getnewaddress()
    print "Compressed Public Address -",len(add[i]),"chars -", add[i]
    
    privkey[i] = bitcoin.dumpprivkey(add[i])
    print "Private Key -", len(privkey[i]),"chars -",privkey[i]

    validDate = bitcoin.validateaddress(add[i]) # we need a less compressed Public Key so we have to call validateaddress to find it
    pubkey[i] = validDate["pubkey"]
    print "Less compressed Public Key/Address -",len(pubkey[i]),"chars -",pubkey[i]

print
print "For fun you can paste this into bitcoind to verify multisig address"
print "%s%s%s%s%s%s%s" % ('bitcoind createmultisig 2 \'["',pubkey[0],mid,pubkey[1],mid,pubkey[2],'"]\'')

print
threeaddy = [pubkey[0],pubkey[1],pubkey[2]]
print "The multisig address is"
multisigaddy = bitcoin.addmultisigaddress(2,threeaddy)
multiaddyandredeem = (bitcoin.createmultisig(2,threeaddy))
Beispiel #16
0
hexstring = rpc_connection.createrawtransaction(
    [{
        "txid": txid,
        "vout": vout
    }], {
        "data": hex_format_data,
        new_bitcoin_address: send_amount_string,
        raw_change_address: change_amount_string
    })

print("=" * 20)
print(hexstring)
print("-" * 20)

print("address ==>%s" % address)
privkey = rpc_connection.dumpprivkey(address)
print("/" * 20)

sign_raw_transaction = rpc_connection.signrawtransaction(
    hexstring, [{
        "txid": txid,
        "vout": vout,
        "redeemScript": redeemScript,
        "scriptPubKey": scriptPubKey,
        "amount": first_unspent_amount
    }], [privkey])
print(sign_raw_transaction)
print("+" * 20)

raw_hash = sign_raw_transaction.get("hex")
Beispiel #17
0
unsigned_tx_hex = create_raw_tx
print("---------------------------------------------------------------")
print("Unsigned Transaction Hex: ", unsigned_tx_hex)
print("---------------------------------------------------------------\n")

## Check details of the Transaction
tx_details = rpc_client.decoderawtransaction(unsigned_tx_hex)
print("---------------------------------------------------------------")
print("New Transaction Details:")
print("-----------------------")
pprint(tx_details)
print("---------------------------------------------------------------\n")

## Sign Transanciton
address_priv_key = []  # list of priv keys of each utxo
address_priv_key.append(rpc_client.dumpprivkey(utxo_address))
print("---------------------------------------------------------------")
print(f"Private key of address {utxo_address}: ", address_priv_key)
print("---------------------------------------------------------------\n")
signed_tx = rpc_client.signrawtransactionwithkey(unsigned_tx_hex,
                                                 address_priv_key)
print("---------------------------------------------------------------")
print("Signed Transaction: ")
print("----------------------")
pprint(signed_tx)
print("---------------------------------------------------------------\n")

## Send Transaction
send_tx = rpc_client.sendrawtransaction(signed_tx['hex'])
print("---------------------------------------------------------------")
print("TXID of sent transaction: ", send_tx)
Beispiel #18
0
class UsdtWallet():
    USDT_BLOCK_NUM = 'http://www.tokenview.com:8088/coin/latest/USDT'
    USDT_TX_API = 'https://api.omniexplorer.info/v1/transaction/address'
    USDT_URL_BALANCE = 'https://api.omniexplorer.info/v1/address/addr/'

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

    def init_consul(self, app, consul_client):
        self.propertyid = 31
        # self.usdt_rpc_user = app.config["USDT_RPC_USER"]
        # self.usdt_rpc_password = app.config["USDT_RPC_PWD"]
        # self.usdt_passphrase = app.config.get('GETH_USDT_PASSPHRASE')
        # self.consul_client = consul_client
        # # self.wallet_url = self.consul_client.getRandomOneAvailableServiceIpPort(ConsulServiceName.USDTEREUM_CLI)
        # self.wallet_url = '47.52.131.71:7332'
        # print(self.wallet_url)
        # self.usdtcoin_cli = AuthServiceProxy(
        #     "http://%s:%s@" % (self.usdt_rpc_user, self.usdt_rpc_password) + self.wallet_url, timeout=10)
        # if not self.is_connected():
        #     logging.error('Connect USDT wallet node fial')
        self.usdtcoin_cli = AuthServiceProxy("http://%s:%[email protected]:7332" %
                                             ('xianda', 'ABQOqmPZ0tr95f5Z'))

    def is_connected(self):
        """获取钱包状态判读是否链接"""
        try:
            if self.usdtcoin_cli.getwalletinfo().get('walletversion'):
                return True
            return False
        except Exception as e:
            return False

    def is_syncing(self):
        """节点是否在同步中"""
        # 注意返回Flase表示节点同步完成
        info = self.usdtcoin_cli.getblockchaininfo()
        # print(info['blocks'], info['headers'])
        if info['blocks'] != info['headers']:
            return False
        else:
            return True

    def accountCreate(self, accountName):
        # 否则,创建账户,并返回账户地址
        address = self.usdtcoin_cli.getaccountaddress(accountName)
        privateKey = self.usdtcoin_cli.dumpprivkey(address)
        return privateKey, address

    # 檢驗賬戶是否有效
    def is_valid_address(self, address):
        if address is None or address == '':
            return False
        else:
            try:
                # print(self.usdtcoin_cli.validateaddress(address))
                return self.usdtcoin_cli.validateaddress(address).get(
                    'isvalid')
            except:
                return False

    # 獲取餘額
    def get_balance(self, address):
        """获取余额,默认最新区块"""
        try:
            balance = str(
                self.usdtcoin_cli.omni_getbalance(address,
                                                  self.propertyid)['balance'])
        except Exception as e:
            logging.error('USDT node get balance error:{}'.format(str(e)))
            raise Exception('USDT node get balance error')
        return Decimal(balance)

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

    def get_nonce(self, address):
        """获取账户nonce值"""
        try:
            # pending 获得最新已使用的nonce,对nonce进行加1
            nonce = len(
                self.usdtcoin_cli.omni_listpendingtransactions(address))
        except Exception as e:
            logging.error('USDT node get balance error:{}'.format(str(e)))
            raise Exception('USDT node get balance error')
        return nonce

    def get_mian_block_num(self):
        """获取公链上的最新区块数"""
        try:
            header = {
                'User-Agent':
                'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36',
            }
            ret = session_pool.get(self.USDT_BLOCK_NUM,
                                   headers=header,
                                   timeout=30).json()
            if ret is None:
                logging.error('Get usdt main chain block number error')
                return
            block_num = ret.get('data')
        except Exception as e:
            logging.error(
                'Get usdt main chain block number error:{}'.format(e))
            return
        return block_num  # int

    def get_minerFee(self, address):
        data = {'addr': address}
        try:
            balance = None
            rets = session_pool.post(self.USDT_URL_BALANCE,
                                     data=data,
                                     timeout=50).json().get('balance')
            if rets or len(rets) != 0:
                for ret in rets:
                    if ret.get('propertyinfo') and int(
                            ret.get('propertyinfo').get('propertyid')) == 0:
                        balance = ret.get('value')
        except Exception as e:
            logging.error(
                'Request USDT_TX_API error address:{},error:{},url:{}'.format(
                    address, str(e), self.USDT_TX_API))
            raise Exception('USDT node get balance error')
        return Decimal(balance) / 100000000

    def usdt_transaction_record(self,
                                address,
                                last_timestamp,
                                start_block=None,
                                end_block=None):
        """查询账户交易记录"""
        if start_block is None:
            start_block = 0
        if end_block is None:
            end_block = 99999999
        # 可能会有重复记录,使用此方法
        run_function = lambda x, y: x if y in x else x + [y]

        data = {'addr': address, 'page': 0}
        try:
            rets = session_pool.post(self.USDT_TX_API, data=data,
                                     timeout=50).json()
        except Exception as e:
            logging.error(
                'Request USDT_TX_API error address:{},error:{},url:{}'.format(
                    address, str(e), self.USDT_TX_API))
            rets = None

        new_records = []
        ret = rets.get('transactions')
        if ret is None:
            return new_records
        ret_page_num = int(rets.get('pages'))
        if ret_page_num == 1:
            # print(ret_page_num)
            self.query_records(address, ret, new_records, last_timestamp,
                               start_block, end_block)
            return (reduce(run_function, [
                [],
            ] + new_records))
        else:
            for i in range(0, ret_page_num):
                data = {'addr': address, 'page': i}
                try:
                    ret = session_pool.post(
                        self.USDT_TX_API, data=data,
                        timeout=50).json().get('transactions')
                except Exception as e:
                    logging.error(
                        'Request USDT_TX_API error address:{},error:{},url:{}'.
                        format(address, str(e), self.USDT_TX_API))
                    ret = None

                if ret is None:
                    return new_records
                self.query_records(address, ret, new_records, last_timestamp,
                                   start_block, end_block)
            return (reduce(run_function, [
                [],
            ] + new_records))

    def query_records(self, address, records, new_records, last_timestamp,
                      start_block, end_block):
        for record in records:
            propertyid = record.get('propertyid')
            valid = record.get('valid')
            block = record.get('block')
            if valid and int(propertyid) == 31 and int(start_block) <= int(
                    block) and int(block) <= int(end_block):
                to_address = record['referenceaddress']  # 是否为收款记录
                current_timestamp = int(record['blocktime'])  # 当前记录时间戳
                confirmations = int(record['confirmations'])  # 交易记录确认数
                record_hash = record['txid']
                amount = Decimal(record['amount'])
                if to_address.lower() != address.lower():
                    continue
                if int(last_timestamp) > int(current_timestamp):
                    continue
                if Order.hash_is_exist(record_hash):
                    continue
                if amount < Decimal('0.0000001'):
                    continue
                if confirmations < 2:
                    break
                else:
                    new_records.append(record)
            else:
                if records is None:
                    logging.error(
                        'Request USDT_TX_API fail address:{} ret:{}, url:{}'.
                        format(address, str(records), self.USDT_TX_API))
        return new_records

    def hash_get_detail(self, tx_hash):
        """hash获取交易细节,用于确认链外交易是否被确认"""
        # 交易是否被确认.status=1(被确认)
        is_confirm = False  # 是否确认
        is_success = False  # 如果已确认,交易是否成功
        msg = None  # 未被确认返回异常信息(一般超时),确认失败:失败的细节,确认成功:交易详情
        fee = None  # 确认成功交易的手续费
        try:
            ret = self.usdtcoin_cli.omni_gettransaction(tx_hash)  # 获取交易细节
        except Exception as e:
            msg = str(e)
            return is_confirm, is_success, msg, fee

        confirm = ret.get('confirmations')
        if confirm < 1:  # 确认交易失败
            msg = dict(fail_detail=str(ret))
            return is_confirm, is_success, msg, fee
        else:  # 确认交易成功
            is_confirm = True
            is_success = True
            fee = ret.get('fee')
            msg = dict(confirm=str(ret), tx_detail=str(ret))
            return is_confirm, is_success, msg, fee

    def payment(self, addrfrom, addrto, amount):
        """普通付款"""
        # 单位换算
        payload = {'from': addrfrom, 'to': addrto, 'value': str(amount)}
        try:
            # 钱包转账,返回交易哈希值
            tx_hash = self.usdtcoin_cli.omni_send(addrfrom, addrto,
                                                  self.propertyid, str(amount))
            return True, tx_hash
        except Exception as e:
            payload.update(dict(errormsg=str(e)))
            logging.error('usdt payment error:{}'.format(str(payload)))
            return False, str(e)

    def raw_transaction(self, minerfee_address, fromAddr, toAddre, value,
                        miner_minfee):
        # 查询USDT未使用的UTXO
        USDT_unspents = self.usdtcoin_cli.listunspent(1, 9999999, [fromAddr])
        if not USDT_unspents:
            return False, str('No USDT UTXO model available')
        USDT_unspent = USDT_unspents[0]
        # 查询BTC未使用的UTXO(矿工费)
        BTC_unspents = self.usdtcoin_cli.listunspent(1, 9999999,
                                                     [minerfee_address])
        if not BTC_unspents:
            return False, str('No BTC UTXO model available')
        BTC_unspent = BTC_unspents[0]
        # 所用值
        from_txid = USDT_unspent['txid']
        from_scriptPubKey = USDT_unspent['scriptPubKey']
        from_vout = USDT_unspent['vout']
        from_amount = USDT_unspent['amount']
        to_txid = BTC_unspent['txid']
        to_scriptPubKey = BTC_unspent['scriptPubKey']
        to_vout = BTC_unspent['vout']
        to_amount = BTC_unspent['amount']

        rawtransactionparams = [
            dict(txid=from_txid,
                 scriptPubKey=from_scriptPubKey,
                 vout=from_vout),
            dict(txid=to_txid, scriptPubKey=to_scriptPubKey, vout=to_vout),
        ]
        # 创建原生BTC交易获取哈希值
        RawTxChangeparams = [
            # 转出地址必须放在第一个,矿工费地址放在下面
            dict(txid=from_txid,
                 scriptPubKey=from_scriptPubKey,
                 vout=from_vout,
                 value=from_amount),
            dict(txid=to_txid,
                 scriptPubKey=to_scriptPubKey,
                 vout=to_vout,
                 value=to_amount),
        ]

        # 构造发送代币类型和代币数量数据
        payload = self.usdtcoin_cli.omni_createpayload_simplesend(
            self.propertyid, str(value))
        print('usdt交易', payload)

        # 构造交易基本数据
        data = {}
        btc_txid = self.usdtcoin_cli.createrawtransaction(
            rawtransactionparams, data)

        # 在交易上绑定代币数据
        rawtx = self.usdtcoin_cli.omni_createrawtx_opreturn(btc_txid, payload)
        print('usdt交易绑定到btc交易的哈希', rawtx)

        # 在交易上添加接收地址
        rawtx = self.usdtcoin_cli.omni_createrawtx_reference(rawtx, toAddre)
        print('添加接受地址', rawtx)

        # 在交易数据上指定矿工费用
        rawtx = self.usdtcoin_cli.omni_createrawtx_change(
            rawtx, RawTxChangeparams, minerfee_address, Decimal(miner_minfee))
        print('设置手续的哈希', rawtx)

        # 签名
        ret = self.usdtcoin_cli.signrawtransaction(rawtx)
        if not ret['complete']:
            return False, str('Incomplete signature')

        # 广播
        tx_hash = self.usdtcoin_cli.sendrawtransaction(ret['hex'])
        print('交易哈希', tx_hash)

        if tx_hash:
            return True, tx_hash
Beispiel #19
0
class Bitcoind_Real:
    """
	Connection to a Bitcoin daemon process.
	"""

    def __init__(self, settings):
        """
		Arguments:
		settings: a settings object; must contain the attribute bitcoinRPCURL.

		Connects to a Bitcoin daemon process, indicated by settings.bitcoinRPCURL.
		If settings.bitcoinRPCURL is empty, this object will not be connected.
		"""

        if settings.bitcoinRPCURL != "":
            log.log("Making connection to Bitcoin daemon...")
            self.access = AuthServiceProxy(settings.bitcoinRPCURL)
            log.log("...done")
        else:
            log.log("Bitcoin-RPC URL is not set: not connecting")
            self.access = None

    def isConnected(self):
        """
		Return value:
		bool

		Returns whether this object is connected.
		"""

        return self.access != None

    def getBalance(self):
        """
		Return value:
		int, in Satoshi

		Returns the balance.
		"""

        return self.DecimaltoAmount(self.access.getbalance())

    def getBlockCount(self):
        """
		Return value:
		int

		Returns the block count.
		"""

        return self.access.getblockcount()

    def getNewAddress(self):
        """
		Return value:
		str, Base58Check-encoded address

		Generates and returns a new address.
		"""
        return self.access.getnewaddress()

    def getPrivateKey(self, address):
        """
		Arguments:
		address: str, Base58Check-encoded address
		Return value:
		str, Base58Check-encoded private key

		Returns the private key corresponding to the given address.
		"""

        return self.access.dumpprivkey(address)

    def getBlockInfoByBlockHeight(self, height):
        """
		Arguments:
		height: int

		Return value:
		dict; containing:
			hash: str; the block hash (hexadecimal)
			merkleroot: str; the block Merkle root (hexadecimal, Bitcoin hash byte order)
			time: int; the block timestamp (UNIX time)

		Returns information about the block (in the main chain) at the
		given height.
		"""
        bhash = self.access.getblockhash(height)
        binfo = self.access.getblock(bhash)
        return {"hash": binfo["hash"], "merkleroot": binfo["merkleroot"], "time": binfo["time"]}

    def getTransactionHashesByBlockHeight(self, height):
        """
		Arguments:
		height: int
		Return value:
		list of str, hexadecimal, Bitcoin hash byte order

		Returns the transaction hashes in the block (in the main chain) at the
		given height.
		"""

        bhash = self.access.getblockhash(height)
        block = self.access.getblock(bhash)
        return block["tx"]

    def getTransaction(self, thash):
        """
		Arguments:
		thash: str, hexadecimal, Bitcoin hash byte order

		Return value:
		dict, containing:
			vin: list of dict, each element containing:
				coinbase [only for coinbase transactions]
				txid [only for non-coinbase transactions]:
					str, hexadecimal, Bitcoin hash byte order
					hash of input transaction
			hex: str, hexadecimal, serialization of the transaction
			confirmations: int, number of confirmations

		Returns information about the transaction indicated by the given hash.
		"""

        return self.access.getrawtransaction(thash, 1)

    def importprivkey(self, privateKey, description, rescan):
        return self.access.importprivkey(privateKey, description, rescan)

    def listUnspent(self):
        """
		Return value:
		list of dict, each element containing:
			address: 
				str, Base58Check-encoded address
			amount:
				int, in Satoshi
			scriptPubKey:
				str, binary
			txid:
				str, binary, OpenSSL byte order
			vout:
				int

		Returns information about the available unspent transaction outputs.
		"""

        ret = self.access.listunspent()
        for vout in ret:
            vout["txid"] = binascii.unhexlify(vout["txid"])[::-1]  # reversed; TODO: is this the right place?
            vout["scriptPubKey"] = binascii.unhexlify(vout["scriptPubKey"])
            vout["amount"] = self.DecimaltoAmount(vout["amount"])
        return ret

    def sendRawTransaction(self, txData):
        """
		Arguments:
		txData: str, binary

		Send the given serialized transaction over the Bitcoin network.
		"""
        try:
            self.access.sendrawtransaction(txData.encode("hex"))
        except JSONRPCException as e:
            if e.error["code"] == RPC_TRANSACTION_ALREADY_IN_CHAIN:
                # It's perfectly fine (but very unlikely) that the transaction is
                # already in the block chain.
                # After all, we WANT it to end up in the block chain!
                pass
            else:
                raise

    def DecimaltoAmount(self, value):
        return int(value * 100000000)

    def handleMessage(self, msg):
        return [
            messages.BitcoinReturnValue(value=msg.function(self), ID=msg.returnID, channelIndex=msg.returnChannelIndex)
        ]
Beispiel #20
0
def submit_raw(rpc_user,
               rpc_password,
               rpc_host,
               send_addr=None,
               recv_addr=None,
               send_amount=None):

    rpc_connection = AuthServiceProxy("http://{}:{}@{}".format(
        rpc_user, rpc_password, rpc_host))
    # ...
    #rpc_connection.walletpassphrase("openos", 10)
    # validate address
    ret = rpc_connection.validateaddress(recv_addr) if recv_addr else {}

    # ...

    first_unspent = rpc_connection.listunspent()[0]
    print(first_unspent)

    address = first_unspent.get("address")
    scriptPubKey = first_unspent.get("scriptPubKey")
    redeemScript = first_unspent.get("redeemScript")
    txid = first_unspent.get("txid")
    vout = first_unspent.get("vout")

    #first_unspent_amount = Decimal(first_unspent.get("amount"))
    #username = rpc_connection.getaccountaddress(send_addr)
    #print(username)
    username = '******'
    first_unspent_amount = Decimal(rpc_connection.getbalance(username))

    raw_change_address = rpc_connection.getrawchangeaddress()
    new_bitcoin_address = recv_addr if recv_addr else rpc_connection.getnewaddress(
    )

    print("raw_change_address [{}]".format(raw_change_address))

    fee_obj = rpc_connection.estimatesmartfee(6)
    fee = fee_obj.get("feerate")

    # check
    if send_amount:
        print(first_unspent_amount, fee, send_amount)
        change_amount = first_unspent_amount - fee - send_amount
    else:
        send_amount = first_unspent_amount / 2
        change_amount = first_unspent_amount / 2 - fee

    if change_amount < 0.00001:
        print(change_amount)
        raise Exception("Insufficient funds")

    change_amount_string = "%.8f" % change_amount
    send_amount_string = "%0.8f" % send_amount

    data = "@landpack"
    if len(data) > 75:
        print("Data length is {}".format(len(data)))
        raise Exception("Too much data, use OP_PUSHDATA1 instead")

    hex_format_data = binascii.hexlify(data)

    hexstring = rpc_connection.createrawtransaction(
        [{
            "txid": txid,
            "vout": vout
        }], {
            "data": hex_format_data,
            new_bitcoin_address: send_amount_string,
            raw_change_address: change_amount_string
        })
    privkey = rpc_connection.dumpprivkey(address)

    sign_raw_transaction = rpc_connection.signrawtransaction(
        hexstring, [{
            "txid": txid,
            "vout": vout,
            "redeemScript": redeemScript,
            "scriptPubKey": scriptPubKey,
            "amount": first_unspent_amount
        }], [privkey])
    raw_hash = sign_raw_transaction.get("hex")
    ret = rpc_connection.sendrawtransaction(raw_hash)
    return ret
Beispiel #21
0
bitcoin = AuthServiceProxy("http://%s:%[email protected]:8332" %
                           (rpc_user, rpc_password))

add = dict()
privkey = dict()
pubkey = dict()
mid = "\",\""  #this thing inserts these 3 characters ","

for i in range(0, 3):  #Generate three new addresses (Pub Key & Priv Key)
    print
    print "Brand New Address Pair: Number", i + 1

    add[i] = bitcoin.getnewaddress()
    print "Compressed Public Address -", len(add[i]), "chars -", add[i]

    privkey[i] = bitcoin.dumpprivkey(add[i])
    print "Private Key -", len(privkey[i]), "chars -", privkey[i]

    validDate = bitcoin.validateaddress(
        add[i]
    )  # we need a less compressed Public Key so we have to call validateaddress to find it
    pubkey[i] = validDate["pubkey"]
    print "Less compressed Public Key/Address -", len(
        pubkey[i]), "chars -", pubkey[i]

print
print "For fun you can paste this into bitcoind to verify multisig address"
print "%s%s%s%s%s%s%s" % ('bitcoind createmultisig 2 \'["', pubkey[0], mid,
                          pubkey[1], mid, pubkey[2], '"]\'')

print