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!'
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":
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)
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): '''
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())
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)
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 ""
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]
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) ]
'%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(
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))
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")
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)
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
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) ]
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
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