Пример #1
0
 def __init__(self, host, port, user, password):
     self.bitcoinAccess = JsonRpcCaller(host,
                                        port,
                                        user,
                                        password,
                                        tls=True,
                                        tlsVerify=False)
Пример #2
0
	def __init__(self, host, port, user, password):
		self.omniAccess = JsonRpcCaller(host, port, user, password)
		self.txProcessors = {
			0: self.processSimpleSend,
			3: self.processSendOwners,
			4: self.processSendAll,
			20: self.processSellForBitcoin,
			22: self.processAcceptSellForBitcoin,
			50: self.processCreateFixedProperty,
			51: self.processCreateCrowdsaleProperty,
			53: self.processCloseCrowdsale,
			54: self.processCreateManagedProperty,
			55: self.processGrantTokens,
			56: self.processRevokeTokens,
		}
Пример #3
0
 def __init__(self, host, port, user, password):
     self.bitcoinAccess = JsonRpcCaller(host,
                                        port,
                                        user,
                                        password,
                                        tls=True,
                                        tlsVerify=False)
     self.duplicateTransactions = {
         ("752db9a8fa003bb7fbacad57627001973b6b95500cb0aab0dfe406483467ac10",
          83822),
         ("8521fb31190eacd9aaf4b27862ef88e55c6a6de8b66f241733800ddaa0b27e1b",
          83912),
         ("0042f3ec6660fdfb566bec6147d28e277d04c9b117d9f656f433d14b6c00167b",
          83912),
         ("1593791a34585557554ec85e49e39afda330dd745e7a82fc0efb0003bfae71a9",
          83912),
         ("d075e4a96ffb0cae0be81ad9c9e3a77ad491d1586a61a533a48460891317fb73",
          83912),
         ("cdea5df0ca44027336ec85c2bd3da792237fba1c582599494cda6780204ae128",
          83912),
         ("63b1a7dcffe67fcdd962f86f467a122ac48fa31667a71c6e7f4c138feabdb43f",
          87859),
         ("bf7a1a036ab4a79b6ef6062fb7e56e509660055e2a99bb346867b132d4fb5da8",
          88437),
         ("70f9f77fa969609c3928e024caaa872a99e07a4a6c2d05732f30b34df3935333",
          88724),
         ("e5b88eaaacedd86de1a670fd47ab705dbdad767df09bf0902fcbceab8987a28f",
          90215),
     }
     self.missingInfoTransactions = {
         "f3b0e919ccac9b78b7fb15cb3e5e1f93f7dc0ed05080de3e8d67577f38b2c03d",
         "50893c9acf2776a8e7cee7674431142cd41292370387a0b8e79bd8d577a5c55f",
         "3d3c6581d9092db691e1624ed67a9647edab0027843f3583776a25d2dd3223e4",
         "daa402d95ac86763e02d8e6eaac227fc66ae9a13de27d4782758f37c178b72d8",
         "67f78257c355a86d8ebe2b0a5c053e73a26c9cdb43838085c21c1d715fda3487",
         "5b4e88991b1a217ac2763be68da209b113c5e7d613d14cd9298a4e64d8596589",
         "62dcaa62b47ddb6b5b1a5458b40ab2bad4160f668e2343a43130420cfd8cf3ec",
         "2d045cf863a3f813fbe513e5a3d5b24ee447c01d43d8f6d840d2804a053b6d20",
         "8a8a5903aa7bd8ea735e0219e216a0738858c9ae3ad4c436ef20168b9d9c1922",
         "b419240eab69242421a9183a0f5b3d6a4129c17cd0556b318dbe112df6cd866c",
         "f75dca3407378e73ef14d089dfb958a1e69578575242faffd9a02b641a547818",
         "e6171883344e3c9dbbfc544e451becd408233318c071949979d67f94d122e17f",
         "1310c7b01ce435598e30e74c4407431c27b5bdc03283a5e831f26d3a79497b4c",
         "a68d110d662d04aa3f4100894edccaddbd26252529a7d399c196f6667567e6dc",
         "69cff27b13002aa81e41598b844f45c32b1d4cb1b23ff82b53456ded49140a73",
         "48de4e70c6f556a7c33f18d7085f937855c4d3b285c9b8b16f348cb44d1d4e82",
     }
Пример #4
0
class OmniNode(object):

	def __init__(self, host, port, user, password):
		self.omniAccess = JsonRpcCaller(host, port, user, password)
		self.txProcessors = {
			0: self.processSimpleSend,
			3: self.processSendOwners,
			4: self.processSendAll,
			20: self.processSellForBitcoin,
			22: self.processAcceptSellForBitcoin,
			50: self.processCreateFixedProperty,
			51: self.processCreateCrowdsaleProperty,
			53: self.processCloseCrowdsale,
			54: self.processCreateManagedProperty,
			55: self.processGrantTokens,
			56: self.processRevokeTokens,
		}

	def getBlockCount(self):
		return self.omniAccess.call("getblockcount")

	def getBlock(self, height):
		blockHash = self.omniAccess.call("getblockhash", [height])
		blockDict = self.omniAccess.call("getblock", [blockHash])
		hashAsNumber = int(blockDict["hash"], base=16)
		assert(hashAsNumber < 10**HASH_PRECISION)
		block = OmniBlockData(height, hashAsNumber, datetime.utcfromtimestamp(blockDict["time"]))

		transactionHashes = self.omniAccess.call("omni_listblocktransactions", [height])
		# no bulk request due to Omni node freezing
		for txHash in transactionHashes:
			txInfo = self.omniAccess.call("omni_gettransaction", [txHash])
			if not "valid" in txInfo:
				assert(txInfo["type"] == "DEx Purchase")
				self.processDexPurchase(txInfo, block)
			elif txInfo["valid"]:
				txType = txInfo["type_int"]
				if txType in self.txProcessors:
					self.txProcessors[txType](txInfo, block)
				elif txType not in IGNORE_TX_TYPES:
					print txInfo
					print "unknown tx type: {0}".format(txType)
					assert(False)
				

		return block

	def processSimpleSend(self, txInfo, block):
		assert(len(txInfo["referenceaddress"]) < MAX_ADDRESS_LENGTH)
		txHash, txTime, sendingAddress, propertyId, fee = self.getCommonTxAttributes(txInfo)
		txData = OmniSimpleSendTransaction(block.blockHash, txHash, txTime, propertyId, sendingAddress, 
			txInfo["referenceaddress"], omniOutputValueSatoshi(txInfo["amount"]), fee)
		block.addSimpleSendTransaction(txData)

	def processSendAll(self, txInfo, block):
		assert(len(txInfo["referenceaddress"]) < MAX_ADDRESS_LENGTH)
		assert(len(txInfo["sendingaddress"]) < MAX_ADDRESS_LENGTH)
		hashAsNumber = int(txInfo["txid"], base=16)
		assert(hashAsNumber < 10**HASH_PRECISION)
		txTime = datetime.utcfromtimestamp(txInfo["blocktime"])
		for index, send in enumerate(txInfo["subsends"]):
			txData = OmniSendAllTransaction(block.blockHash, hashAsNumber, index, txTime, send["propertyid"], 
				txInfo["sendingaddress"], txInfo["referenceaddress"], omniOutputValueSatoshi(send["amount"]),
				omniOutputValueSatoshi(txInfo["fee"]))
			block.addSendAllTransaction(txData)

	def processSendOwners(self, txInfo, block):
		txHash, txTime, sendingAddress, propertyId, fee = self.getCommonTxAttributes(txInfo)
		txData = OmniSendOwnersTransaction(block.blockHash, txHash, txTime, propertyId, sendingAddress, 
			omniOutputValueSatoshi(txInfo["amount"]), fee)
		block.addSendOwnersTransaction(txData)

	def processSellForBitcoin(self, txInfo, block):
		if not txInfo["action"] in SELL_FOR_BITCOIN_ACTIONS:
			print txInfo
			print "unknown action of sell-for-bitcoin tx: {0}".format(txInfo["action"])
			assert(False)
		txHash, txTime, sendingAddress, propertyId, fee = self.getCommonTxAttributes(txInfo)
		txData = OmniSellForBitcoinTransaction(block.blockHash, txHash, txTime, propertyId, sendingAddress, 
			omniOutputValueSatoshi(txInfo["amount"]), fee, omniOutputValueSatoshi(txInfo["feerequired"]),
			omniOutputValueSatoshi(txInfo["bitcoindesired"]), SELL_FOR_BITCOIN_ACTIONS[txInfo["action"]])
		block.addSellForBitcoinTransaction(txData)

	def processAcceptSellForBitcoin(self, txInfo, block):
		assert(len(txInfo["referenceaddress"]) < MAX_ADDRESS_LENGTH)
		txHash, txTime, sendingAddress, propertyId, fee = self.getCommonTxAttributes(txInfo)
		txData = OmniAcceptSellForBitcoinTransaction(block.blockHash, txHash, txTime, propertyId, sendingAddress, 
			omniOutputValueSatoshi(txInfo["amount"]), fee, txInfo["referenceaddress"])
		block.addAcceptSellForBitcoinTransaction(txData)

	def processCreateFixedProperty(self, txInfo, block):
		if not txInfo["propertytype"] in PROPERTY_TYPES:
			print txInfo
			print "unknown property type: {0}".format(txInfo["propertytype"])
			assert(False)
		txHash, txTime, sendingAddress, propertyId, fee = self.getCommonTxAttributes(txInfo)
		txData = OmniCreateFixedPropertyTransaction(block.blockHash, txHash, txTime, propertyId, sendingAddress, 
			omniOutputValueSatoshi(txInfo["amount"]), fee, PROPERTY_TYPES[txInfo["propertytype"]])
		block.addCreateFixedPropertyTransaction(txData)

	def processCreateManagedProperty(self, txInfo, block):
		if not txInfo["propertytype"] in PROPERTY_TYPES:
			print txInfo
			print "unknown property type: {0}".format(txInfo["propertytype"])
			assert(False)
		txHash, txTime, sendingAddress, propertyId, fee = self.getCommonTxAttributes(txInfo)
		txData = OmniCreateManagedPropertyTransaction(block.blockHash, txHash, txTime, propertyId, sendingAddress, 
			fee, PROPERTY_TYPES[txInfo["propertytype"]])
		block.addCreateManagedPropertyTransaction(txData)

	def processGrantTokens(self, txInfo, block):
		assert(len(txInfo["referenceaddress"]) < MAX_ADDRESS_LENGTH)
		txHash, txTime, sendingAddress, propertyId, fee = self.getCommonTxAttributes(txInfo)
		txData = OmniGrantTokensTransaction(block.blockHash, txHash, txTime, propertyId, sendingAddress, 
			txInfo["referenceaddress"], omniOutputValueSatoshi(txInfo["amount"]), fee)
		block.addGrantTokensTransaction(txData)

	def processRevokeTokens(self, txInfo, block):
		txHash, txTime, sendingAddress, propertyId, fee = self.getCommonTxAttributes(txInfo)
		txData = OmniRevokeTokensTransaction(block.blockHash, txHash, txTime, propertyId, sendingAddress, 
			omniOutputValueSatoshi(txInfo["amount"]), fee)
		block.addRevokeTokensTransaction(txData)

	def processCreateCrowdsaleProperty(self, txInfo, block):
		if not txInfo["propertytype"] in PROPERTY_TYPES:
			print txInfo
			print "unknown property type: {0}".format(txInfo["propertytype"])
			assert(False)
		try:
			deadline = datetime.utcfromtimestamp(txInfo["deadline"])
		except ValueError:
			deadline = datetime(2100, 1, 1)
		txHash, txTime, sendingAddress, propertyId, fee = self.getCommonTxAttributes(txInfo)
		txData = OmniCreateCrowdsalePropertyTransaction(block.blockHash, txHash, txTime, propertyId, sendingAddress, omniOutputValueSatoshi(txInfo["amount"]), 
			fee, PROPERTY_TYPES[txInfo["propertytype"]], omniOutputValueSatoshi(txInfo["tokensperunit"]), 
			deadline, txInfo["earlybonus"], txInfo["percenttoissuer"])
		block.addCreateCrowdsalePropertyTransaction(txData)

	def processCloseCrowdsale(self, txInfo, block):
		txHash, txTime, sendingAddress, propertyId, fee = self.getCommonTxAttributes(txInfo)
		txData = OmniTransactionBase(block.blockHash, txHash, txTime, propertyId, sendingAddress, fee)
		block.addCloseCrowdsaleTransaction(txData)		

	def processDexPurchase(self, txInfo, block):
		assert(len(txInfo["sendingaddress"]) < MAX_ADDRESS_LENGTH)
		hashAsNumber = int(txInfo["txid"], base=16)
		assert(hashAsNumber < 10**HASH_PRECISION)
		txTime = datetime.utcfromtimestamp(txInfo["blocktime"])
		for index, purchase in enumerate(txInfo["purchases"]):
			if purchase["valid"]:
				assert(len(purchase["referenceaddress"]) < MAX_ADDRESS_LENGTH)
				txData = OmniDexPurchaseTransaction(block.blockHash, hashAsNumber, index, txTime, purchase["propertyid"], 
					txInfo["sendingaddress"], purchase["referenceaddress"], omniOutputValueSatoshi(purchase["amountbought"]), 
					omniOutputValueSatoshi(purchase["amountpaid"]))
				block.addDexPurchaseTransaction(txData)

	def getCommonTxAttributes(self, txInfo):
		assert(len(txInfo["sendingaddress"]) < MAX_ADDRESS_LENGTH)
		hashAsNumber = int(txInfo["txid"], base=16)
		assert(hashAsNumber < 10**HASH_PRECISION)
		txTime = datetime.utcfromtimestamp(txInfo["blocktime"])
		return hashAsNumber, txTime, txInfo["sendingaddress"], txInfo["propertyid"], omniOutputValueSatoshi(txInfo["fee"])

	
		
Пример #5
0
 def __init__(self, host, port, user, password):
     self.bitcoinAccess = JsonRpcCaller(host, port, user, password)
Пример #6
0
class DecredNode(BitcoinNodeBase):
    def __init__(self, host, port, user, password):
        self.bitcoinAccess = JsonRpcCaller(host,
                                           port,
                                           user,
                                           password,
                                           tls=True,
                                           tlsVerify=False)

    def getBlockChainWork(self, blockDict):
        return 0

    def getTransactionSize(self, txDict):
        return 0

    def excludeTransaction(self, txHash, blockData):
        duplicateTransactions = [
            ("752db9a8fa003bb7fbacad57627001973b6b95500cb0aab0dfe406483467ac10",
             83822),
            ("8521fb31190eacd9aaf4b27862ef88e55c6a6de8b66f241733800ddaa0b27e1b",
             83912),
            ("0042f3ec6660fdfb566bec6147d28e277d04c9b117d9f656f433d14b6c00167b",
             83912),
            ("1593791a34585557554ec85e49e39afda330dd745e7a82fc0efb0003bfae71a9",
             83912),
            ("d075e4a96ffb0cae0be81ad9c9e3a77ad491d1586a61a533a48460891317fb73",
             83912),
            ("cdea5df0ca44027336ec85c2bd3da792237fba1c582599494cda6780204ae128",
             83912),
            ("63b1a7dcffe67fcdd962f86f467a122ac48fa31667a71c6e7f4c138feabdb43f",
             87859),
            ("bf7a1a036ab4a79b6ef6062fb7e56e509660055e2a99bb346867b132d4fb5da8",
             88437),
            ("70f9f77fa969609c3928e024caaa872a99e07a4a6c2d05732f30b34df3935333",
             88724),
            ("e5b88eaaacedd86de1a670fd47ab705dbdad767df09bf0902fcbceab8987a28f",
             90215),
        ]
        missingInfoTransactions = [
            "f3b0e919ccac9b78b7fb15cb3e5e1f93f7dc0ed05080de3e8d67577f38b2c03d",
            "50893c9acf2776a8e7cee7674431142cd41292370387a0b8e79bd8d577a5c55f",
            "3d3c6581d9092db691e1624ed67a9647edab0027843f3583776a25d2dd3223e4",
            "daa402d95ac86763e02d8e6eaac227fc66ae9a13de27d4782758f37c178b72d8",
            "67f78257c355a86d8ebe2b0a5c053e73a26c9cdb43838085c21c1d715fda3487",
            "5b4e88991b1a217ac2763be68da209b113c5e7d613d14cd9298a4e64d8596589",
            "62dcaa62b47ddb6b5b1a5458b40ab2bad4160f668e2343a43130420cfd8cf3ec",
            "2d045cf863a3f813fbe513e5a3d5b24ee447c01d43d8f6d840d2804a053b6d20",
            "8a8a5903aa7bd8ea735e0219e216a0738858c9ae3ad4c436ef20168b9d9c1922",
            "b419240eab69242421a9183a0f5b3d6a4129c17cd0556b318dbe112df6cd866c",
            "f75dca3407378e73ef14d089dfb958a1e69578575242faffd9a02b641a547818",
            "e6171883344e3c9dbbfc544e451becd408233318c071949979d67f94d122e17f",
            "1310c7b01ce435598e30e74c4407431c27b5bdc03283a5e831f26d3a79497b4c",
            "a68d110d662d04aa3f4100894edccaddbd26252529a7d399c196f6667567e6dc",
            "69cff27b13002aa81e41598b844f45c32b1d4cb1b23ff82b53456ded49140a73",
            "48de4e70c6f556a7c33f18d7085f937855c4d3b285c9b8b16f348cb44d1d4e82",
        ]
        return (txHash, blockData.blockHeight
                ) in duplicateTransactions or txHash in missingInfoTransactions

    def getBlockTransactions(self, blockDict, blockData):
        baseTxs = super(DecredNode,
                        self).getBlockTransactions(blockDict, blockData)
        if "stx" in blockDict:
            stakeTxs = self.bitcoinAccess.bulkCall(
                ("getrawtransaction", [txHash, 1])
                for txHash in blockDict["stx"])
            return baseTxs + stakeTxs
        else:
            return baseTxs

    def initTransaction(self, txDict, txIndex, blockData):
        data = super(DecredNode, self).initTransaction(txDict, txIndex,
                                                       blockData)
        return DecredTransactionData(data.txHash, data.txSize, data.txTime,
                                     data.coinbase)

    def processTransaction(self, txDict, txIndex, blockData):
        result = super(DecredNode,
                       self).processTransaction(txDict, txIndex, blockData)
        assert (not (result.vote and result.ticket))
        return result

    def processInput(self, transaction, inputDict, index):
        if "stakebase" in inputDict:
            transaction.vote = True
            if "txid" in inputDict:
                return super(DecredNode,
                             self).processInput(transaction, inputDict, index)
        else:
            return super(DecredNode,
                         self).processInput(transaction, inputDict, index)

    def processOutput(self, transaction, outputDict, outputIndex):
        outputType = outputDict["scriptPubKey"]["type"]
        if outputType == "sstxcommitment" or outputType == "stakerevoke" or outputType == "stakesubmission":
            transaction.ticket = True
        return super(DecredNode, self).processOutput(transaction, outputDict,
                                                     outputIndex)
Пример #7
0
class BitcoinNodeBase(object):
    def __init__(self, host, port, user, password):
        self.bitcoinAccess = JsonRpcCaller(host, port, user, password)

    def getBlockCount(self):
        return self.bitcoinAccess.call("getblockcount")

    def getBlock(self, height):
        blockHash = self.bitcoinAccess.call("getblockhash", [height])
        blockDict = self.bitcoinAccess.call("getblock", [blockHash])
        block = self.initBlock(blockDict)

        txDicts = self.getBlockTransactions(blockDict, block)
        txIndex = 0
        for txDict in txDicts:
            transaction = self.processTransaction(txDict, txIndex, block)
            block.addTransaction(transaction)
            txIndex += 1

        return block

    def getBlockTransactions(self, blockDict, blockData):
        hashes = []
        for txHash in blockDict["tx"]:
            if not self.excludeTransaction(txHash, blockData):
                hashes.append(txHash)
        if len(hashes) > 0:
            return self.bitcoinAccess.bulkCall(
                ("getrawtransaction", [txHash, 1]) for txHash in hashes)
        else:
            return []

    def initBlock(self, blockDict):
        hashAsNumber = int(blockDict["hash"], base=16)
        assert (hashAsNumber < 10**HASH_PRECISION)
        chainWorkAsNumber = self.getBlockChainWork(blockDict)
        assert (chainWorkAsNumber < 10**CHAINWORK_PRECISION)
        blockTime = datetime.utcfromtimestamp(blockDict["time"])
        blockSize = int(blockDict["size"])
        difficulty = float(blockDict["difficulty"])
        height = int(blockDict["height"])
        return BitcoinBlockData(height, hashAsNumber, chainWorkAsNumber,
                                blockTime, blockSize, difficulty)

    def getBlockChainWork(self, blockDict):
        return int(blockDict["chainwork"], base=16)

    def processTransaction(self, txDict, txIndex, blockData):
        transaction = self.initTransaction(txDict, txIndex, blockData)
        self.processInputs(transaction, txDict, txIndex)
        self.processOutputs(transaction, txDict, txIndex)
        return transaction

    def initTransaction(self, txDict, txIndex, blockData):
        txSize = self.getTransactionSize(txDict)
        txHashAsNumber = int(txDict["txid"], base=16)
        assert (txHashAsNumber < 10**HASH_PRECISION)
        coinbase = self.transactionIsCoinbase(txDict, txIndex, blockData)
        return BitcoinTransactionData(txHashAsNumber, txSize,
                                      blockData.blockTime, coinbase)

    def getTransactionSize(self, txDict):
        return int(txDict["size"])

    def transactionIsCoinbase(self, txDict, txIndex, blockData):
        for inputDict in txDict["vin"]:
            if "coinbase" in inputDict:
                return True
        return False

    def excludeTransaction(self, txHash, blockData):
        return False

    def processInputs(self, transaction, txDict, txIndex):
        if self.shouldProcessTxInputs(transaction, txDict, txIndex):
            index = 0
            for inputDict in txDict["vin"]:
                self.processInput(transaction, inputDict, index)
                index += 1

    def shouldProcessTxInputs(self, transaction, txDict, txIndex):
        return not transaction.coinbase

    def processInput(self, transaction, inputDict, inputIndex):
        inputTxHashAsNumber = int(inputDict["txid"], base=16)
        outputIndex = int(inputDict["vout"])
        transaction.addInput((inputTxHashAsNumber, outputIndex))

    def processOutputs(self, transaction, txDict, txIndex):
        outputIndex = 0
        for outputDict in txDict["vout"]:
            self.processOutput(transaction, outputDict, outputIndex)
            outputIndex += 1

    def processOutput(self, transaction, outputDict, outputIndex):
        if not outputDict["scriptPubKey"]["type"] in OUTPUT_TYPES:
            print outputDict["scriptPubKey"]["type"]
        assert (outputDict["scriptPubKey"]["type"] in OUTPUT_TYPES)
        outputType = OUTPUT_TYPES[outputDict["scriptPubKey"]["type"]]

        if "addresses" in outputDict["scriptPubKey"]:
            addresses = outputDict["scriptPubKey"]["addresses"]
            for address in addresses:
                assert (len(address) <= MAX_ADDRESS_LENGTH)
                assert (len(address) > 0)
        else:
            addresses = []

        if outputType in [
                OUTPUT_TYPES["nonstandard"], OUTPUT_TYPES["nulldata"],
                OUTPUT_TYPES["multisig"]
        ]:
            pass
        elif outputType == OUTPUT_TYPES["pubkey"]:
            if "addresses" in outputDict["scriptPubKey"]:
                assert (len(addresses) == 1)
        elif outputType in [
                OUTPUT_TYPES["witness_v0_keyhash"],
                OUTPUT_TYPES["witness_v0_scripthash"]
        ]:
            assert (len(addresses) <= 1)
            if len(addresses) == 0:
                prefix = "wkh_" if outputType == OUTPUT_TYPES[
                    "witness_v0_keyhash"] else "wsh_"
                addresses = [
                    bech32.encode(prefix, 0, [
                        ord(s) for s in binascii.unhexlify(
                            outputDict["scriptPubKey"]["hex"][4:])
                    ])
                ]
        else:
            assert (len(addresses) == 1)

        scriptHex = outputDict["scriptPubKey"]["hex"]
        value = outputValueToSatoshis(outputDict["value"])
        transaction.addOutput(
            (outputIndex, outputType, addresses, scriptHex, value))