コード例 #1
0
    def compareConstructedTX(self):
        self.maxDiff = None
        self.op = operations.Call_order_update(
            **{
                "fee": {
                    "amount": 100,
                    "asset_id": "1.3.0"
                },
                "delta_debt": {
                    "amount": 10000,
                    "asset_id": "1.3.22"
                },
                "delta_collateral": {
                    "amount": 100000000,
                    "asset_id": "1.3.0"
                },
                "funding_account": "1.2.29",
                "extensions": {
                    "target_collateral_ratio": 12345
                },
            })
        ops = [Operation(self.op)]
        tx = Signed_Transaction(
            ref_block_num=ref_block_num,
            ref_block_prefix=ref_block_prefix,
            expiration=expiration,
            operations=ops,
        )
        tx = tx.sign([wif], chain=prefix)
        tx.verify([PrivateKey(wif).pubkey], prefix)
        txWire = hexlify(bytes(tx)).decode("ascii")
        print("=" * 80)
        pprint(tx.json())
        print("=" * 80)

        # Test against Bitshares backened
        self.cm = bitshares.rpc.get_transaction_hex(tx.json())

        print("soll: %s" % self.cm[:-130])
        print("ist:  %s" % txWire[:-130])
        print(txWire[:-130] == self.cm[:-130])
        self.assertEqual(self.cm[:-130], txWire[:-130])
コード例 #2
0
    def sign(self):
        """ Sign a provided transaction with the provided key(s)

            :param dict tx: The transaction to be signed and returned
            :param string wifs: One or many wif keys to use for signing
                a transaction. If not present, the keys will be loaded
                from the wallet as defined in "missing_signatures" key
                of the transactions.
        """
        self.constructTx()

        if "operations" not in self or not self["operations"]:
            return

        # Legacy compatibility!
        # If we are doing a proposal, obtain the account from the proposer_id
        if self.blockchain.proposer:
            proposer = Account(self.blockchain.proposer,
                               blockchain_instance=self.blockchain)
            self.wifs = set()
            self.signing_accounts = list()
            self.appendSigner(proposer["id"], "active")

        # We need to set the default prefix, otherwise pubkeys are
        # presented wrongly!
        if self.blockchain.rpc:
            operations.default_prefix = (
                self.blockchain.rpc.chain_params["prefix"])
        elif "blockchain" in self:
            operations.default_prefix = self["blockchain"]["prefix"]

        try:
            signedtx = Signed_Transaction(**self.json())
        except:
            raise ValueError("Invalid TransactionBuilder Format")

        if not any(self.wifs):
            raise MissingKeyError

        signedtx.sign(self.wifs, chain=self.blockchain.rpc.chain_params)
        self["signatures"].extend(signedtx.json().get("signatures"))
        return signedtx
コード例 #3
0
 def test_proposal_update(self):
     op = operations.Proposal_update(
         **{
             'fee_paying_account': "1.2.1",
             'proposal': "1.10.90",
             'active_approvals_to_add': ["1.2.5"],
             "fee": objects.Asset(amount=12512, asset_id="1.3.0"),
         })
     ops = [Operation(op)]
     tx = Signed_Transaction(ref_block_num=ref_block_num,
                             ref_block_prefix=ref_block_prefix,
                             expiration=expiration,
                             operations=ops)
     tx = tx.sign([wif], chain=prefix)
     tx.verify([PrivateKey(wif).pubkey], "BTS")
     txWire = hexlify(bytes(tx)).decode("ascii")
     compare = ("f68585abf4dce7c804570117e03000000000000000015a01050000000"
                "000000001203255378db6dc19443e74421c954ad7fdcf23f4ea45fe4f"
                "e5a1b078a0f94fb529594819c9799d68efa5cfb5b271a9333a2f516ca"
                "4fb5093226275f48a42d9e8cf")
     self.assertEqual(compare[:-130], txWire[:-130])
コード例 #4
0
    def test_pricefeed(self):
        feed = objects.PriceFeed(
            **{
                "settlement_price":
                objects.Price(
                    base=objects.Asset(amount=214211, asset_id="1.3.0"),
                    quote=objects.Asset(amount=1241, asset_id="1.3.14"),
                ),
                "core_exchange_rate":
                objects.Price(
                    base=objects.Asset(amount=1241, asset_id="1.3.0"),
                    quote=objects.Asset(amount=6231, asset_id="1.3.14"),
                ),
                "maximum_short_squeeze_ratio":
                1100,
                "maintenance_collateral_ratio":
                1750,
            })

        op = operations.Asset_publish_feed(fee=objects.Asset(amount=100,
                                                             asset_id="1.3.0"),
                                           publisher="1.2.0",
                                           asset_id="1.3.3",
                                           feed=feed)
        ops = [Operation(op)]
        tx = Signed_Transaction(ref_block_num=ref_block_num,
                                ref_block_prefix=ref_block_prefix,
                                expiration=expiration,
                                operations=ops)
        tx = tx.sign([wif], chain=prefix)
        tx.verify([PrivateKey(wif).pubkey], "BTS")
        txWire = hexlify(bytes(tx)).decode("ascii")

        compare = ("f68585abf4dce7c8045701136400000000000000000003c344030"
                   "00000000000d9040000000000000ed6064c04d904000000000000"
                   "0057180000000000000e0000012009e13f9066fedc3c8c1eb2ac3"
                   "3b15dc67ecebf708890d0f8ab62ec8283d1636002315a189f1f5a"
                   "a8497b41b8e6bb7c4dc66044510fae25d8f6aebb02c7cdef10")
        self.assertEqual(compare[:-130], txWire[:-130])
コード例 #5
0
    def compareConstructedTX(self):
        #    def test_online(self):
        #        self.maxDiff = None
        op = operations.Worker_create(
            **{
                "fee": {
                    "amount": 0,
                    "asset_id": "1.3.0"
                },
                "owner": "1.2.0",
                "work_begin_date": "1970-01-01T00:00:00",
                "work_end_date": "1970-01-01T00:00:00",
                "daily_pay": 0,
                "name": "Myname",
                "url": "myURL",
                "initializer": [1, {
                    "pay_vesting_period_days": 125
                }]
            })
        ops = [Operation(op)]
        tx = Signed_Transaction(ref_block_num=ref_block_num,
                                ref_block_prefix=ref_block_prefix,
                                expiration=expiration,
                                operations=ops)
        tx = tx.sign([wif], chain=prefix)
        tx.verify([PrivateKey(wif).pubkey], "BTS")
        txWire = hexlify(bytes(tx)).decode("ascii")
        print("=" * 80)
        pprint(tx.json())
        print("=" * 80)

        from grapheneapi.grapheneapi import GrapheneAPI
        rpc = GrapheneAPI("localhost", 8092)
        compare = rpc.serialize_transaction(tx.json())
        print("soll: %s" % compare[:-130])
        print("ist:  %s" % txWire[:-130])
        print(txWire[:-130] == compare[:-130])
        self.assertEqual(compare[:-130], txWire[:-130])
コード例 #6
0
    def doit(self, printWire=False):
        ops = [Operation(self.op)]
        tx = Signed_Transaction(ref_block_num=ref_block_num,
                                ref_block_prefix=ref_block_prefix,
                                expiration=expiration,
                                operations=ops)
        tx = tx.sign([wif], chain=prefix)
        tx.verify([PrivateKey(wif).pubkey], prefix)
        txWire = hexlify(bytes(tx)).decode("ascii")
        if printWire:
            print()
            print(txWire)
            print()
        self.assertEqual(self.cm[:-130], txWire[:-130])

        if TEST_AGAINST_CLI_WALLET:
            from grapheneapi.grapheneapi import GrapheneAPI
            rpc = GrapheneAPI("localhost", 8092)
            self.cm = rpc.serialize_transaction(tx.json())
            # print("soll: %s" % self.cm[:-130])
            # print("ist:  %s" % txWire[:-130])
            # print(txWire[:-130] == self.cm[:-130])
            self.assertEqual(self.cm[:-130], txWire[:-130])
コード例 #7
0
 def test_upgrade_account(self):
     op = operations.Account_upgrade(
         **{
             "fee": {
                 "amount": 0,
                 "asset_id": "1.3.0"
             },
             "account_to_upgrade": "1.2.0",
             "upgrade_to_lifetime_member": True,
             "prefix": prefix,
         })
     ops = [Operation(op)]
     tx = Signed_Transaction(ref_block_num=ref_block_num,
                             ref_block_prefix=ref_block_prefix,
                             expiration=expiration,
                             operations=ops)
     tx = tx.sign([wif], chain=prefix)
     tx.verify([PrivateKey(wif).pubkey], "BTS")
     txWire = hexlify(bytes(tx)).decode("ascii")
     compare = ("f68585abf4dce7c804570108000000000000000000000100000"
                "11f4e42562ada1d3fed8f8eb51dd58117e3a4024959c46955a0"
                "0d2a7e7e8b40ae7204f4617913aaaf028248d43e8c3463b8776"
                "0ca569007dba99a2c49de75bd69b3")
     self.assertEqual(compare[:-130], txWire[:-130])
コード例 #8
0
    def compareNewWire(self):
        #    def test_online(self):
        #        self.maxDiff = None

        from grapheneapi.grapheneapi import GrapheneAPI
        rpc = GrapheneAPI("localhost", 8092)
        tx = rpc.create_account("xeroc", "fsafaasf", "", False)
        pprint(tx)
        compare = rpc.serialize_transaction(tx)
        ref_block_num = tx["ref_block_num"]
        ref_block_prefix = tx["ref_block_prefix"]
        expiration = tx["expiration"]

        ops = [Operation(operations.Account_create(**tx["operations"][0][1]))]
        tx = Signed_Transaction(ref_block_num=ref_block_num,
                                ref_block_prefix=ref_block_prefix,
                                expiration=expiration,
                                operations=ops)
        tx = tx.sign([wif], chain=prefix)
        tx.verify([PrivateKey(wif).pubkey], "BTS")
        txWire = hexlify(bytes(tx)).decode("ascii")
        print("\n")
        print(txWire[:-130])
        print(compare[:-130])
コード例 #9
0
    def compareConstructedTX(self):
        #    def test_online(self):
        #        self.maxDiff = None
        op = operations.Vesting_balance_withdraw(
            **{
                "fee": {
                    "amount": 0,
                    "asset_id": "1.3.0"
                },
                "vesting_balance": "1.13.0",
                "owner": "1.2.0",
                "amount": {
                    "amount": 0,
                    "asset_id": "1.3.0"
                },
                "prefix": "TEST"
            })
        ops = [Operation(op)]
        tx = Signed_Transaction(ref_block_num=ref_block_num,
                                ref_block_prefix=ref_block_prefix,
                                expiration=expiration,
                                operations=ops)
        tx = tx.sign([wif], chain=prefix)
        tx.verify([PrivateKey(wif).pubkey], "BTS")
        txWire = hexlify(bytes(tx)).decode("ascii")
        print("=" * 80)
        pprint(tx.json())
        print("=" * 80)

        from grapheneapi.grapheneapi import GrapheneAPI
        rpc = GrapheneAPI("localhost", 8092)
        compare = rpc.serialize_transaction(tx.json())
        print(compare[:-130])
        print(txWire[:-130])
        print(txWire[:-130] == compare[:-130])
        self.assertEqual(compare[:-130], txWire[:-130])
コード例 #10
0
 def test_limit_order_cancel(self):
     op = operations.Limit_order_cancel(
         **{
             "fee": {
                 "amount": 0,
                 "asset_id": "1.3.0"
             },
             "fee_paying_account": "1.2.104",
             "order": "1.7.51840",
             "extensions": []
         })
     ops = [Operation(op)]
     tx = Signed_Transaction(ref_block_num=ref_block_num,
                             ref_block_prefix=ref_block_prefix,
                             expiration=expiration,
                             operations=ops)
     tx = tx.sign([wif], chain=prefix)
     tx.verify([PrivateKey(wif).pubkey], "BTS")
     txWire = hexlify(bytes(tx)).decode("ascii")
     compare = ("f68585abf4dce7c8045701020000000000000000006880950300000"
                "11f3fb754814f3910c1a8845486b86057d2b4588ae559b4c3810828"
                "c0d4cbec0e5b23517937cd7e0cc5ee8999d0777af7fe56d3c4b2e58"
                "7421bfb7400d4efdae97a")
     self.assertEqual(compare[:-130], txWire[:-130])
コード例 #11
0
 def test_create_account(self):
     s = {
         "fee": {
             "amount": 1467634,
             "asset_id": "1.3.0"
         },
         "registrar": "1.2.33",
         "referrer": "1.2.27",
         "referrer_percent": 3,
         "name": "foobar-f124",
         "owner": {
             "weight_threshold":
             1,
             "account_auths": [],
             'key_auths':
             [['BTS6pbVDAjRFiw6fkiKYCrkz7PFeL7XNAfefrsREwg8MKpJ9VYV9x', 1],
              ['BTS6zLNtyFVToBsBZDsgMhgjpwysYVbsQD6YhP3kRkQhANUB4w7Qp', 1]],
             "address_auths": []
         },
         "active": {
             "weight_threshold":
             1,
             "account_auths": [],
             'key_auths':
             [['BTS6pbVDAjRFiw6fkiKYCrkz7PFeL7XNAfefrsREwg8MKpJ9VYV9x', 1],
              ['BTS6zLNtyFVToBsBZDsgMhgjpwysYVbsQD6YhP3kRkQhANUB4w7Qp', 1],
              ['BTS8CemMDjdUWSV5wKotEimhK6c4dY7p2PdzC2qM1HpAP8aLtZfE7', 1]],
             "address_auths": []
         },
         "options": {
             "memo_key":
             "BTS5TPTziKkLexhVKsQKtSpo4bAv5RnB8oXcG4sMHEwCcTf3r7dqE",
             "voting_account": "1.2.5",
             "num_witness": 0,
             "num_committee": 0,
             "votes": [],
             "extensions": []
         },
         "extensions": {}
     }
     op = operations.Account_create(**s)
     ops = [Operation(op)]
     tx = Signed_Transaction(ref_block_num=ref_block_num,
                             ref_block_prefix=ref_block_prefix,
                             expiration=expiration,
                             operations=ops)
     tx = tx.sign([wif], chain=prefix)
     tx.verify([PrivateKey(wif).pubkey], "BTS")
     txWire = hexlify(bytes(tx)).decode("ascii")
     compare = ("f68585abf4dce7c804570105f26416000000000000211b03000b666f"
                "6f6261722d6631323401000000000202fe8cc11cc8251de6977636b5"
                "5c1ab8a9d12b0b26154ac78e56e7c4257d8bcf6901000314aa202c91"
                "58990b3ec51a1aa49b2ab5d300c97b391df3beb34bb74f3c62699e01"
                "000001000000000303b453f46013fdbccb90b09ba169c388c34d8445"
                "4a3b9fbec68d5a7819a734fca0010002fe8cc11cc8251de6977636b5"
                "5c1ab8a9d12b0b26154ac78e56e7c4257d8bcf6901000314aa202c91"
                "58990b3ec51a1aa49b2ab5d300c97b391df3beb34bb74f3c62699e01"
                "0000024ab336b4b14ba6d881675d1c782912783c43dbbe31693aa710"
                "ac1896bd7c3d61050000000000000000011f61ad276120bc3f189296"
                "2bfff7db5e8ce04d5adec9309c80529e3a978a4fa1073225a6d56929"
                "e34c9d2a563e67a8f4a227e4fadb4a3bb6ec91bfdf4e57b80efd")
     self.assertEqual(compare[:-130], txWire[:-130])
コード例 #12
0
    def test_jsonLoading(self):
        data1 = {
            "expiration":
            expiration,
            "ref_block_num":
            ref_block_num,
            "ref_block_prefix":
            ref_block_prefix,
            "extensions": [],
            "operations": [[
                0, {
                    "amount": {
                        "amount": 1000000,
                        "asset_id": "1.3.4"
                    },
                    "extensions": [],
                    "fee": {
                        "amount": 0,
                        "asset_id": "1.3.0"
                    },
                    "from": "1.2.0",
                    "memo": {
                        "from":
                        "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
                        "message":
                        "fa5b6e83079a878e499e2e52a76a7739e9de40986a8e3bd8a68ce316cee50b21",
                        "nonce":
                        5862723643998573708,
                        "to":
                        "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
                    },
                    "to": "1.2.1"
                }
            ]],
            "signatures": [
                "1f6c1e8df5faf18c3b057ce713ec92f9" +
                "b487c1ba58138daabc0038741b402c93" +
                "0d63d8d63861740215b4f65eb8ac9185" +
                "a3987f8239b962181237f47189e21102" + "af"
            ]
        }
        a = Signed_Transaction(data1.copy())
        data2 = a.json()

        check1 = data1
        check2 = data2
        for key in [
                "expiration", "extensions", "ref_block_num",
                "ref_block_prefix", "signatures"
        ]:
            self.assertEqual(check1[key], check2[key])

        check1 = data1["operations"][0][1]
        check2 = data2["operations"][0][1]
        for key in ["from", "to"]:
            self.assertEqual(check1[key], check2[key])

        check1 = data1["operations"][0][1]["memo"]
        check2 = data2["operations"][0][1]["memo"]
        for key in check1:
            self.assertEqual(check1[key], check2[key])
コード例 #13
0
def sign_transaction(transaction, wifs):
    """ This methed signs a raw/unsigned transaction with the provided private
        keys.

        .. note:: The method does not guarantee that the blockchain will accept
            the signed transaction. This may happen in multiple cases, such as
            a) signed with irrelevant or redundant private keys, b)
            insufficient permissions to perform what is requested in the
            operations.

        .. note:: This method does **not** have a connection to the blockchain.
            Hence, neither the expiration, nor any of the TaPOS parameters
            (``ref_block_num``, nor ``ref_block_prefix``) are obtained here.
            The method needs to be provided with a fully valid (but unsigned
            transaction).

        An unsigned transaction takes the following form:

        .. code-block: js

            {
                "ref_block_num": 49506,
                "ref_block_prefix": 2292772274,
                "expiration": "2018-01-25T08:29:00",
                "operations": [[
                    2, {
                        "fee": {
                            "amount": 9,
                            "asset_id": "1.3.0"},
                        "fee_paying_account": "1.2.126225",
                        "order": "1.7.49956139",
                        "extensions": []}]],
                "extensions": [],
                "signatures": [],
            }

        The operation (here, operation type (0) is a ``transfer``) is the
        actual action that should take place on the blockchain. The parameters
        around it are required for a valid transaction and need to be obtained
        outside this method.


        For sake of completion, we here describe how the ``ref_block_num`` and
        ``ref_block_prefix`` are obtained from the blockchain
        (`github <https://github.com/xeroc/python-graphenelib/blob/master/graphenebase/transactions.py#L18-L26>`_):

        .. code-block:: python

            dynBCParams = rpc.get_dynamic_global_properties()
            ref_block_num = dynBCParams["head_block_number"] & 0xFFFF
            ref_block_prefix = struct.unpack_from("<I", unhexlify(dynBCParams["head_block_id"]), 4)[0]

        .. important:: The expiration **must not** be more than 1 day in the future!

        :param dict transaction: unsigned transaction
        :param list wifs: list of private keys in wif format
        :rtype: dict
        :returns: signed transaction

    """
    # Instantiate Signed_Transaction with content
    assert isinstance(transaction, dict)
    assert isinstance(wifs, (list, tuple, set))

    prefix = "BTS"
    if transaction["operations"][0][1].get("prefix", "BTS") != "BTS":
        # call transaction signer
        prefix = transaction["operations"][0][1]["prefix"]
    if transaction.get("prefix", "BTS") != "BTS":
        prefix = transaction["prefix"]
        for idx, item in enumerate(transaction["operations"]):
            transaction["operations"][idx][1].update(
                {"prefix": transaction["prefix"]})

    tx = Signed_Transaction(**transaction)
    # call transaction signer
    result = tx.sign(wifs, chain=prefix).json()
    result["transaction_id"] = tx.id
    return result
コード例 #14
0
with open(args.file) as f:
    obj = json.load(f)
    blockchain = BitShares(args.node)
    if args.tapos:
        txbuffer = blockchain.tx()
        obj['ref_block_num'] = txbuffer['ref_block_num']
        obj['ref_block_prefix'] = txbuffer['ref_block_prefix']
        if args.expire and int(args.expire) >= 1:
            expiration = datetime.strptime(
                txbuffer['expiration'], "%Y-%m-%dT%H:%M:%S") + timedelta(
                    minutes=int(args.expire) - 1, seconds=30)
            txbuffer['expiration'] = expiration.strftime("%Y-%m-%dT%H:%M:%S%Z")
        obj['expiration'] = txbuffer['expiration']
    tx = Signed_Transaction(
        ref_block_num=obj['ref_block_num'],
        ref_block_prefix=obj['ref_block_prefix'],
        expiration=obj['expiration'],
        operations=obj['operations'],
    )
    if args.chain_id is None:
        args.chain_id = blockchain.rpc.chain_params['chain_id']
    signData = encode(binascii.unhexlify(args.chain_id), tx)
    print(binascii.hexlify(signData).decode())

    dongle = getDongle(True)
    offset = 0
    first = True
    singSize = len(signData)
    while offset != singSize:
        if singSize - offset > 200:
            chunk = signData[offset:offset + 200]
        else:
コード例 #15
0
ファイル: history.py プロジェクト: sUbc0ol/citadel
    def mergeHistory_before(self, iso, account):
        self.refreshing = True

        #iso._wait_online(timeout=3) # will raise exception
        #if not(iso.is_connected()):
        #	raise Exception

        # subscribe
        rpc = iso.bts.rpc
        if not self.subscribed:
            rpc.get_full_accounts([account.name], True)
            self.subscribed = True

        # fetch history
        last_op_index = iso.store.historyStorage.getLastOperation(account.name)
        log.debug("Last OP INDEX for %s = %s" % (account.name, last_op_index))

        # recreate account object
        #from bitshares.account import Account
        #account = Account(account.name, bitshares_instance=iso.bts)

        # load from the net
        history = list(account.history())

        # load full tx from net + generate description
        t = 0
        for h in history:
            if (h['id'] == last_op_index):
                break
            t += 1
            #print("Get full tx for",
            #	int(h['block_num']), int(h['trx_in_block']),
            #	int(h['op_in_trx']), int(h["virtual_op"]))
            try:
                ftx = iso.bts.rpc.get_transaction(int(h['block_num']),
                                                  int(h['trx_in_block']))
            except Exception as error:
                #print(str(error))
                ftx = {}
            #print(ftx)
            h['_fulltx_dict'] = ftx
            h['_fulltx_obj'] = Signed_Transaction(**ftx) if ftx else None
            h['_fulltx'] = json.dumps(ftx)

            h['_memo'] = 0
            try:
                if h['op'][0] == 0:
                    h['_memo'] = -1
                    if "memo" in h['op'][1]:
                        data = h['op'][1]['memo']
                        clear = iso.getMemo(None, None, data=data)
                        if len(clear["message"]) > 0:
                            h['_memo'] = 1
            except Exception as e:
                #import traceback
                #print(h['op'][1], "failed to metch memo-data")
                #traceback.print_exc()
                pass

            #print("Get description for", h)
            h['_details'] = iso.historyDescription(h, account)
            h['_icon'] = ":/op/images/op/" + h['_details']['icon'] + ".png"
            h['description'] = h['_details'].pop('long')
            h['details'] = json.dumps(h['_details'])

        history = history[0:t]
        return (history, account.name, iso)
コード例 #16
0
	def mergeHistory_before(self, iso, account, request_handler=None):
		self.refreshing = True
		
		#iso._wait_online(timeout=3) # will raise exception
		#if not(iso.is_connected()):
		#	raise Exception
		
		rh = request_handler
		
		# subscribe
		rpc = iso.bts.rpc
		if not self.subscribed:
			rpc.get_full_accounts([account.name], True)
			self.subscribed = True
		
		# fetch history
		last_op_index = iso.store.historyStorage.getLastOperation(account.name)
		log.debug("Last OP INDEX for %s = %s" % (account.name, last_op_index))
		
		# recreate account object
		#from bitshares.account import Account
		#account = Account(account.name, blockchain_instance=iso.bts)
		
		# load from the net
		history = list(account.history())
		
		# load full tx from net + generate description
		total = len(history)
		t = 0
		for h in history:
			if rh and rh.cancelled:
				break
			if (h['id'] == last_op_index):
				break
			t += 1
			if rh:
				rh.ping(int(t / total * 100), None)
			#print("Get full tx for",
			#	int(h['block_num']), int(h['trx_in_block']),
			#	int(h['op_in_trx']), int(h["virtual_op"]))
			try:
				ftx = iso.bts.rpc.get_transaction(int(h['block_num']), int(h['trx_in_block']))
			except Exception as error:
				log.error("Failed to get transaction %d in block %d: %s", int(h['trx_in_block']), int(h['block_num']), str(error))
				#print(str(error))
				ftx = { }
			#print(ftx)
			h['_fulltx_obj' ] = Signed_Transaction(**ftx) if ftx else None
			if not "operations" in ftx and h["op"][0] == 2: # cancel order
				ftx = {
					"operations": [ h["op"] ],
					"operation_results": [ h["result"] ]
				}
			h['_fulltx_dict'] = ftx
			h['_fulltx'] = json.dumps(ftx)
			
			h['_memo'] = 0
			import bitshares.exceptions
			try:
				if h['op'][0] == 0:
					h['_memo'] = -1
					if "memo" in h['op'][1]:
						data = h['op'][1]['memo']
						clear = iso.getMemo(None, None, data=data)
						if len(clear["message"]) > 0:
							h['_memo'] = 1
			except bitshares.exceptions.WalletLocked:
				h['_memo'] = 1
			except Exception as e:
				log.error("Could not decode memo in op %s: %s", h['id'], str(e))
			
			#print("Get description for", h)
			h['_details'] = iso.historyDescription(h, account)
			h['_icon'] = ":/op/images/op/"+h['_details']['icon']+".png"
			h['description'] = h['_details'].pop('long')
			h['details'] = json.dumps(h['_details'])
		
		history = history[0:t]
		return (history, account.name, iso)
コード例 #17
0
def sendTip(to_name):
    #
    #  `to_name` is account name (string) of recipient.
    #
    Logger.Write("Preparing to send %.1f %s to \"%s\"..." %
                 (tip_amount, tip_asset_display_symbol, to_name))
    tx_head = blockchain.new_tx()  # Pull recent TaPoS
    try:
        dummy = tx_head[
            'ref_block_num']  # Somehow this triggers tx_head to populate 'expiration'... (??)
    except NumRetriesReached:
        Logger.Write(
            "ERROR: Can't reach API node: 'NumRetries' reached.  Check network connection."
        )
        return
    expiration = datetime.strptime(tx_head['expiration'],
                                   "%Y-%m-%dT%H:%M:%S") + timedelta(minutes=10)
    tx_head['expiration'] = expiration.strftime(
        "%Y-%m-%dT%H:%M:%S%Z"
    )  # Longer expiration to accomodate device interaction
    try:
        tx = append_transfer_tx(tx_head, to_name)
    except:
        Logger.Write("Could not construct transaction.  Please try again.")
        return
    print("We have constructed the following transaction:")
    print(tx)
    tx_st = Signed_Transaction(
        ref_block_num=tx['ref_block_num'],
        ref_block_prefix=tx['ref_block_prefix'],
        expiration=tx['expiration'],
        operations=tx['operations'],
    )
    signData = encode(
        binascii.unhexlify(blockchain.rpc.chain_params['chain_id']), tx_st)
    print("Serialized:")
    print(binascii.hexlify(signData).decode())
    donglePath = parse_bip32_path(bip32_path)
    pathSize = int(len(donglePath) / 4)
    try:
        dongle = getDongle(True)
    except:
        Logger.Write("Ledger Nano not found! Is it plugged in and unlocked?")
        return
    Logger.Write(
        "Created transaction.  Please review and confirm on Ledger Nano S...")
    offset = 0
    first = True
    signSize = len(signData)
    while offset != signSize:
        if signSize - offset > 200:
            chunk = signData[offset:offset + 200]
        else:
            chunk = signData[offset:]

        if first:
            totalSize = len(donglePath) + 1 + len(chunk)
            apdu = binascii.unhexlify("B5040000" + "{:02x}".format(
                totalSize) + "{:02x}".format(pathSize)) + donglePath + chunk
            first = False
        else:
            totalSize = len(chunk)
            apdu = binascii.unhexlify("B5048000" +
                                      "{:02x}".format(totalSize)) + chunk

        offset += len(chunk)
        try:
            result = dongle.exchange(apdu)
        except CommException as e:
            dongle.close()
            if e.sw == 0x6e00:
                Logger.Write(
                    "BitShares App not running on Nano.  Please check.")
            else:
                Logger.Write(
                    "Tx Not Broadcast.  User declined - transaction not signed."
                )
            return
        except:
            dongle.close()
            Logger.Write("An unknown error occured.  Was device unplugged?")
            return
        print(binascii.hexlify(result).decode())
    dongle.close()
    Logger.Write("Broadcasting transaction...")
    tx_sig = blockchain.new_tx(json.loads(str(tx_st)))
    tx_sig["signatures"].extend([binascii.hexlify(result).decode()])
    try:
        print(blockchain.broadcast(tx=tx_sig))
        Logger.Write("Success!  Transaction has been sent.")
    except RPCError as e:
        Logger.Write("Could not broadcast transaction!")
        Logger.Write(str(e))
    except NumRetriesReached:
        Logger.Write(
            "ERROR: Could not broadcast transaction: 'NumRetries' reached.  Check network connection."
        )
    except:
        raise