def process(rpc_connection, account="*", tx_counts=10000, skips=0): commands = [["omni_listtransactions", account, tx_counts, skips]] data = rpc_connection.batch_(commands) #print("----------") #print(data) #print("----------") from utils import filtered keys = [ "txid", "sendingaddress", "referenceaddress", "amount", "propertyid", "blocktime", "confirmations", "block" ] retData = [] for item in data[0]: if "referenceaddress" not in item: continue if item["referenceaddress"].strip() not in g_exUserAddrs: #print( item["referenceaddress"].strip() ) continue if int(str(item["type_int"])) != 0: continue # simple-send if not bool(item["valid"]): #防止假交易 2019-06-13 yqq logging.warning("%s is invalid usdt deposit tx" % item["txid"]) continue #print("%s is valid tx" % item["txid"]) if ":18332" in OMNI_RPC_URL: #测试网 if int(str(item["propertyid"])) != 2: continue # 2 for USDT testnet elif ":8332" in OMNI_RPC_URL: #主网 if int(str(item["propertyid"])) != 31: continue # 31 for USDT mainnet else: return [] retData.append(item) return [filtered(item, keys) for item in retData]
def process(rpc_connection, blknumber, txindex): txdata = rpc_connection.owt_getTransactionByBlockNumberAndIndex( blknumber, txindex) from utils import filtered, alterkeyname return filtered(alterkeyname(txdata, 'hash', 'txid'), [ "nonce", "hash", "from", "to", "value", "gas", "gasPrice" ]) if txdata else False
def process(rpc_connection,account="*",tx_counts=10,skips=0,include_watchonly=True): #add 'include_watchonly' to include those address's transactions which not import private key into the wallet. #yqq 2019-03-26 commands = [["listtransactions",account,tx_counts,skips, include_watchonly]] data = rpc_connection.batch_(commands) if len(data) == 0: return [] txs = [item for item in data[0] if "blocktime" in item and item["category"] == "receive"] #fix bug:only return those txs which be writen into blockchain @yqq 2019-03-21 from utils import filtered return [filtered(item,["address","category","amount","confirmations","txid","blocktime"]) for item in txs][::-1]
def process(rpcconn,from_addr,to_addr,amount): # utxos all = BTC_ListUTXO.utxo(rpcconn,from_addr) # recommend from utils import recommended selected,aggregate = recommended(all,amount) # check if enough from utils import calcFee if not isinstance(amount, Decimal): amount = Decimal(str(amount)) fee = calcFee(len(selected)) if aggregate < fee + amount: return False,"budget not enough" # make augmentations from utils import filtered param_in = [filtered(item,["txid","vout"]) for item in selected] param_out = {to_addr:amount,from_addr:aggregate-amount-fee} print("--------------param_out-------------") print("fee" + str(fee)) print(param_in) print(param_out) print("--------------param_out-------------") # create raw transaction commands = [["createrawtransaction",param_in,param_out]] return True, {"hex":rpcconn.batch_(commands),"utxos":selected, "txout":param_out}
def process(rpc_connection, txid): commands = [["omi_gettransaction", txid]] transaction = rpc_connection.batch_(commands) from utils import filtered return filtered(transaction, [ "txid", "sendingaddress", "referenceaddress", "amount", "propertyid", "blocktime", "confirmations", "block" ])
def calcprevtx(rpc_connection,addr,amount): # utxos all = BTC_ListUTXO.utxo(rpc_connection,addr) # recommend from utils import recommended selected,aggregate = recommended(all,amount) # make augmentations from utils import filtered return [filtered(item,["txid","vout","amount","redeemScript","scriptPubKey"]) for item in selected]
def post(self): omni_rpc_connection = AuthServiceProxy(OMNI_RPC_URL)#todo-junying-20190313 try: # get arguments from_addr = self.get_argument("from") if self.get_argument("from") else 'mtwEVo8FVJrMcms1GyzhbTUSafwDKvyjsq' to_addr = self.get_argument("to") if self.get_argument("to") else 'mzkUX6sZ3bSqK7wk8sZmrR7wUwY3QJQVaE' amount = self.get_argument("amount") fee = Decimal(self.get_argument("fee")) if self.get_argument("fee") else Decimal(OMNI_TRANSACTION_FEE) # utxos from btc.handler import BTC_ListUTXO all = BTC_ListUTXO.utxo(omni_rpc_connection,from_addr) # recommend from utils import recommended selected,aggregate = recommended(all,fee) # check if enough from utils import calcFee fee_ = max(fee,calcFee(len(selected))) if aggregate < fee_: self.write(json.dumps(BaseHandler.error_ret_with_data("budget not enough"))) return # omni_createpayload_simplesend rawdata1 = OMNI_CreateRawTransaction.omni_createpayload_simplesend(omni_rpc_connection,amount) # createrawtransaction from utils import filtered # deletekey(selected,u'vout'); addkey(selected,u'vout',1) param_in = [filtered(item,["txid","vout"]) for item in selected] param_out = {from_addr:aggregate - fee_} rawdata2 = OMNI_CreateRawTransaction.createrawtransaction(omni_rpc_connection,param_in,param_out) # omni_createrawtx_opreturn rawdata3 = OMNI_CreateRawTransaction.omni_createrawtx_opreturn(omni_rpc_connection,rawdata2,rawdata1) # omni_createrawtx_reference rawdata4 = OMNI_CreateRawTransaction.omni_createrawtx_reference(omni_rpc_connection,rawdata3,to_addr) # omni_createrawtx_change param_in = [filtered(item,["txid","vout","scriptPubKey","amount"]) for item in selected] from utils import distribute param_in = distribute(param_in,'amount','value',aggregate - fee_) rawhex = OMNI_CreateRawTransaction.omni_createrawtx_change(omni_rpc_connection,rawdata4,param_in,from_addr,fee_) # return self.write(json.dumps(BaseHandler.success_ret_with_data({"hex":rawhex,"utxos":selected}), default=decimal_default)) except Exception as e: self.write(json.dumps(BaseHandler.error_ret_with_data("error: %s"%e))) print("OMNI_CreateRawTransaction error:{0} in {1}".format(e,get_linenumber()))
def process(rpcconn, from_addr, to_addr, amount): #utxos utxos = BTC_ListUTXO.utxo(rpcconn, from_addr) #print(utxos) def UtxoFilter(utxos, amount): selected = [] from decimal import Decimal nSum = Decimal('0') #最小输入utxo金额 : 148 * rate 其中rate是 1000字节 所需的btc数量 nFee = Decimal('0.0') for utxo in [ item for item in utxos if int(item["confirmations"]) >= 1 and float(item["amount"]) > 0.0003 ]: selected.append(utxo) nSum += Decimal(str((utxo["amount"]))) if nSum > Decimal(str(amount)): nFee = BTC_EstimateSmartFee.calcFee( rpcconn, len(selected), 2) if nSum > nFee + amount: break return selected, nSum, nFee selected, nSum, fee = UtxoFilter(utxos, amount) # check if enough # from utils import calcFee if not isinstance(amount, Decimal): amount = Decimal(str(amount)) # fee = BTC_EstimateSmartFee.calcFee(rpcconn, len(selected), 2) if nSum < fee + amount: return False, "budget not enough" #return False,0 #需测试!!! from utils import filtered param_in = [filtered(item, ["txid", "vout"]) for item in selected] param_out = {to_addr: amount, from_addr: nSum - amount - fee} #print("--------------param_out-------------") #print("fee" + str(fee)) #print(param_in) #print(param_out) #print("--------------param_out-------------") # create raw transaction commands = [["createrawtransaction", param_in, param_out]] return True, { "hex": rpcconn.batch_(commands), "utxos": selected, "txout": param_out }
def process(rpcconn,src,dest): # preprocess param_out = BTC_CreateRawTransactionEx.generateOutParam(dest) ret,utxos,redundant = BTC_CreateRawTransactionEx.genearateInParam(rpcconn,src,param_out) if not ret: return False, "budget not enough" # param_out refinement param_out[src[0]] = redundant if src[0] not in param_out.keys() else param_out[src[0]] + redundant print(param_out) # param_in refinement from utils import filtered param_in = [filtered(item,["txid","vout"]) for item in utxos] print(param_in) return True, {"hex":rpcconn.batch_([["createrawtransaction",param_in,param_out]]),"utxos":utxos, "txout":param_out}
def process(rpcconn, lstSrc, lstDest): #lstSrcAddrs = [] bRet, utxos, txAmount, fTxFee = BTC_CreateRawTransactionEx_Collection.makeParams( rpcconn, lstSrc, lstDest) if not bRet: return False, "collection amount is too small!" strDst = lstDest[0] vout = {strDst: txAmount} from utils import filtered vin = [filtered(item, ["txid", "vout"]) for item in utxos] strHex = rpcconn.batch_([["createrawtransaction", vin, vout]]) return True, { "hex": strHex, "utxos": utxos, "txout": vout, "txFee": fTxFee }
def process(rpc_connection, blknumber, txindex): txdata = rpc_connection.eth_getTransactionByBlockNumberAndIndex( blknumber, txindex) blockData = rpc_connection.eth_getBlockByNumber(blknumber) txdata["blocktime"] = blockData[ "timestamp"] if blockData and "timestamp" in blockData else 0 txdata["confirmations"] = ETH_BlockNumber.latest( rpc_connection) - blknumber txdata["blockNumber"] = blknumber from utils import filtered, alterkeyname retData = filtered(alterkeyname(txdata, 'hash', 'txid'), [ "confirmations", "blocktime", "blockNumber", "nonce", "txid", "from", "to", "value", "gas", "gasPrice" ]) if txdata else False for key in ["nonce", "gas", "value", "gasPrice", "blocktime"]: if "0x" in retData[key]: retData[key] = str(int(retData[key], 16)) getcontext().prec = 30 dValue = RoundDown(Decimal(retData[key]) / Decimal(10**18)) if key in ["value"]: retData[key] = "%.8f" % dValue return retData
def process(rpc_connection,account="*",tx_counts=10,skips=0): commands = [["omni_listtransactions",account,tx_counts,skips]] data = rpc_connection.batch_(commands) from utils import filtered return [filtered(item,["txid","sendingaddress","referenceaddress","amount","propertyid","blocktime","confirmations","block"]) for item in data[0]]
def post(self): omni_rpc_connection = AuthServiceProxy(OMNI_RPC_URL) rpcconn = omni_rpc_connection try: # get arguments src = self.get_argument_ex("src") dest = self.get_argument_ex("dest") if not isinstance(src, list): self.write( json.dumps( BaseHandler.error_ret_with_data( "error: %s" % ("src must be json list")))) return if not isinstance(dest, list): self.write( json.dumps( BaseHandler.error_ret_with_data( "error: %s" % ("dest must be json list")))) return mapUsdtAmount = OMNI_CollectionQuery.process(rpcconn, src) strDstAddr = dest[0] #获取支付手续费地址(目的地址)的utxo集(最小是0.0001) payFeeUtxos = OMNI_GetCollectionOnceCount.process( rpcconn, strDstAddr, 0) import copy tmpPayFeeUtxos = copy.deepcopy(payFeeUtxos) logging.info("payFeeUtxos : {}".format(payFeeUtxos)) results = [] for strSrcAddr, strUsdtAmount in mapUsdtAmount.items(): if len(tmpPayFeeUtxos) == 0: break def getMinUtxo(tmpUtxos): nTmpMin = 1 << 32 minUTXO = None for utxo in tmpUtxos: if utxo['amount'] < nTmpMin: nTmpMin = utxo['amount'] minUTXO = utxo return minUTXO #选择发送usdt的地址的一个utxo(最小的utxo , 一般是0.00000546) tmpUtxos = uBTC_ListUTXO.utxo(rpcconn, strSrcAddr, 1, 999999999) minUsdtSenderUtxo = getMinUtxo(tmpUtxos) logging.info("min utxo:{}".format(minUsdtSenderUtxo)) #选择一个支付手续费的utxo(tmpPayFeeUtxos剩下最小的) minPayFeeUtxo = getMinUtxo(tmpPayFeeUtxos) logging.info("min pay fee utxo:{}".format(minPayFeeUtxo)) tmpPayFeeUtxos.remove(minPayFeeUtxo) #删除这个utxo, 防止双花错误 logging.info("tmpPayFeeUtxos : {}".format(tmpPayFeeUtxos)) #return from utils import filtered vin = [] vin.append(filtered(minUsdtSenderUtxo, ["txid", "vout"])) #必须把发送USDT的地址放在第一个 vin.append(filtered(minPayFeeUtxo, ["txid", "vout"])) vout = {} #先填空即可 # createrawtransaction 创建btc交易作为负载交易 rawtx1 = OMNI_CreateRawTransactionEx_Collection.createrawtransaction( rpcconn, vin, vout) logging.info("rawtx1: {}".format(rawtx1)) # omni_createpayload_simplesend 创建usdt交易 rawtx2 = OMNI_CreateRawTransactionEx_Collection.omni_createpayload_simplesend( rpcconn, strUsdtAmount) logging.info("rawtx2: {}".format(rawtx2)) # omni_createrawtx_opreturn 将usdt交易绑定到btc交易上 rawtx3 = OMNI_CreateRawTransactionEx_Collection.omni_createrawtx_opreturn( rpcconn, rawtx1, rawtx2) logging.info("rawtx3: {}".format(rawtx3)) #return # omni_createrawtx_reference 添加usdt接收地址 rawtx4 = OMNI_CreateRawTransactionEx_Collection.omni_createrawtx_reference( rpcconn, rawtx3, strDstAddr) logging.info("rawtx4 : {}".format(rawtx4)) # omni_createrawtx_change 添加找零地址和手续费, 注意: 字段名时 'value' 不是 'amount' vin = [] vin.append( {'txid':minUsdtSenderUtxo['txid'], \ "vout":minUsdtSenderUtxo['vout'],\ "scriptPubKey":minUsdtSenderUtxo['scriptPubKey'], \ "value": '%.8f'%minUsdtSenderUtxo['amount']} ) vin.append( {'txid':minPayFeeUtxo['txid'], \ "vout":minPayFeeUtxo['vout'], \ "scriptPubKey":minPayFeeUtxo['scriptPubKey'],\ "value": '%.8f'%minPayFeeUtxo['amount'] } ) logging.info("vin : {}".format(vin)) vout = {} nLeft = (minUsdtSenderUtxo['amount'] + minPayFeeUtxo['amount']) - Decimal('0.0001') if nLeft < 0.0001: #全部用掉 strFee = '%.8f' % minPayFeeUtxo['amount'] vout[strDstAddr] = '0.00000546' else: #strFee = '%.8f' % minPayFeeUtxo['amount'] strFee = '0.00010000' vout[strDstAddr] = '%.8f' % nLeft rawtx5 = OMNI_CreateRawTransactionEx_Collection.omni_createrawtx_change( rpcconn, rawtx4, vin, strDstAddr, str(strFee)) logging.info("rawtx5: {}".format(rawtx5)) results.append({ "hex": rawtx5, "utxos": [minUsdtSenderUtxo, minPayFeeUtxo], "txout": vout, "txFee": strFee, "tokenAmount": strUsdtAmount, "tokenId": OMNI_PROPERTY_ID }) logging.info("results:{}".format(results)) self.write( json.dumps(BaseHandler.success_ret_with_data(results), default=decimal_default)) except Exception as e: self.write( json.dumps(BaseHandler.error_ret_with_data("error: %s" % e))) logging.error( "OMNI_CreateRawTransactionEx_Collection error:{0} in {1}". format(e, get_linenumber()))
def post(self): rpcconn = AuthServiceProxy(OMNI_RPC_URL) try: lstSrcAddrs = self.get_argument_ex("src") lstMapDstAddrs = self.get_argument_ex("dst") #参数检查 if not isinstance(lstSrcAddrs, list): self.write( json.dumps( BaseHandler.error_ret_with_data( "error: %s" % ("src must be json list")))) return if not isinstance(lstMapDstAddrs, list): self.write( json.dumps( BaseHandler.error_ret_with_data( "error: %s" % ("dst must be json list")))) return if len(lstSrcAddrs) == 0: self.write( json.dumps( BaseHandler.error_ret_with_data("error: %s" % ("src is empty")))) return if len(lstMapDstAddrs) == 0: self.write( json.dumps( BaseHandler.error_ret_with_data("error: %s" % ("dst is empty")))) return strSrcAddr = lstSrcAddrs[0].strip() #获取支付手续费地址(目的地址)的utxo集(最小是0.0001 + 0.00000546) def chooseUTXO(rpcconn, addr): utxos = uBTC_ListUTXO.utxo(rpcconn, addr, 0) utxosRet = [] for utxo in utxos: nAmount = utxo['amount'] if nAmount >= 0.0001 + 0.00000546: utxosRet.append(utxo) return utxosRet payFeeUtxos = chooseUTXO(rpcconn, strSrcAddr) import copy tmpPayFeeUtxos = copy.deepcopy(payFeeUtxos) #1.判断UTXO数量是否足够 if len(tmpPayFeeUtxos) < len(lstMapDstAddrs): self.write( json.dumps( BaseHandler.error_ret_with_data( "error: %s" % ("src have not enough UTXO")))) return #2.判断src地址USDT余额是否够 strSrcBalance = OMNI_CreateRawTransaction.omni_getbalance( rpcconn, strSrcAddr) dSrcBalance = Decimal(strSrcBalance) dTxSum = Decimal('0.0') #需要转出的总金额 for mapItem in lstMapDstAddrs: amount = mapItem['amount'] if Decimal(str(amount)) <= Decimal('0.0'): self.write( json.dumps( BaseHandler.error_ret_with_data( "error: %s" % ("src UTXO illegal")))) return dTxSum += Decimal(str(amount)) if dSrcBalance < dTxSum: self.write( json.dumps( BaseHandler.error_ret_with_data( "error: %s" % ("src address have not enough USDT balance")))) return retRawTxs = [] #3.找零地址必须是src地址 for mapItem in lstMapDstAddrs: strDstAddr = mapItem['addr'] strUsdtAmount = mapItem['amount'] strOrderId = mapItem['orderId'] #添加orderId区分不同提币订单, 原样返回 def getMinUtxo(tmpUtxos): nTmpMin = 1 << 32 minUTXO = None for utxo in tmpUtxos: if utxo['amount'] < nTmpMin: nTmpMin = utxo['amount'] minUTXO = utxo return minUTXO #关于这个utxo的金额,应该是 minPayFeeUtxo = getMinUtxo(tmpPayFeeUtxos) #获取最小的utxo tmpPayFeeUtxos.remove(minPayFeeUtxo) logging.info("tmpPayFeeUtxos : {}".format(tmpPayFeeUtxos)) from utils import filtered vin = [] vin.append(filtered(minPayFeeUtxo, ["txid", "vout"])) vout = {} #先填空即可 # createrawtransaction 创建btc交易作为负载交易 rawtx1 = OMNI_CreateRawTransactionEx_Collection.createrawtransaction( rpcconn, vin, vout) logging.info("rawtx1 : {}".format(rawtx1)) # omni_createpayload_simplesend 创建usdt交易 rawtx2 = OMNI_CreateRawTransactionEx_Collection.omni_createpayload_simplesend( rpcconn, strUsdtAmount) logging.info("rawtx2: {}".format(rawtx2)) # omni_createrawtx_opreturn 将usdt交易绑定到btc交易上 rawtx3 = OMNI_CreateRawTransactionEx_Collection.omni_createrawtx_opreturn( rpcconn, rawtx1, rawtx2) logging.info("rawtx3 : {}".format(rawtx3)) # omni_createrawtx_reference 添加usdt接收地址 rawtx4 = OMNI_CreateRawTransactionEx_Collection.omni_createrawtx_reference( rpcconn, rawtx3, strDstAddr) logging.info("rawtx4: {}".format(rawtx4)) # omni_createrawtx_change 添加找零地址和手续费, 注意: 字段名时 'value' 不是 'amount' vin = [] vin.append( {'txid':minPayFeeUtxo['txid'], \ "vout":minPayFeeUtxo['vout'], \ "scriptPubKey":minPayFeeUtxo['scriptPubKey'],\ "value": '%.8f'%minPayFeeUtxo['amount'] } ) logging.info("vin : {}".format(vin)) vout = {} nLeft = minPayFeeUtxo['amount'] - Decimal('0.0001') - Decimal( '0.00000546') if nLeft < 0.0001: logging.info("use all") strFee = '%.8f' % ( minPayFeeUtxo['amount'] - Decimal('0.00000546')) #全部用掉 vout[strDstAddr] = '0.00000546' else: logging.info("use 0.00001000") strFee = '0.00010000' vout[strDstAddr] = '0.00000546' vout[strSrcAddr] = '%.8f' % nLeft #找零地址 logging.info('vout {0}'.format(vout)) # 找零地址必须是src地址 rawtx5 = OMNI_CreateRawTransactionEx_Collection.omni_createrawtx_change( rpcconn, rawtx4, vin, strSrcAddr, str(strFee)) logging.info("rawtx5: {}".format(rawtx5)) retRawTxs.append({"orderId":strOrderId, "hex": rawtx5, "utxos":[minPayFeeUtxo], "txout":vout, \ "txFee":strFee, "tokenAmount":strUsdtAmount, "tokenId":OMNI_PROPERTY_ID}) self.write( json.dumps(BaseHandler.success_ret_with_data(retRawTxs), default=decimal_default)) except Exception as e: self.write( json.dumps(BaseHandler.error_ret_with_data("error: %s" % e))) logging.error("OMNI_CreateRawTransaction error:{0} in {1}".format( e, get_linenumber()))
def calcprevtx(rpcconn,src,dest): ret,utxos,redundant = BTC_CreateRawTransactionEx.genearateInParam(rpcconn,src,dest) from utils import filtered return [filtered(item,["txid","vout","amount","redeemScript","scriptPubKey"]) for item in utxos]