def from_raw(self, rb: pb.Block, status: pb.BlockResponse.Status) -> Block: """Deserializes a protobuf object to update this object's members. Args: rb: The protobuf object. status: The status of the `Block`. Returns: Itself. """ self.status = Block.Status(status) self.hash = rb.hash self.version = rb.version self.parent_hash = rb.parent_hash self.tx_merkle_hash = rb.tx_merkle_hash self.tx_receipt_merkle_hash = rb.tx_receipt_merkle_hash self.number = rb.number self.witness = rb.witness self.time = rb.time self.gas_usage = rb.gas_usage self.tx_count = rb.tx_count self.info = Block.Info().from_raw(rb.info) self.transactions = [ Transaction().from_raw(tx) for tx in rb.transactions ] if rb.transactions is not None else [] for transaction in self.transactions: if self.status == Block.Status.IRREVERSIBLE: transaction.status = Transaction.Status.IRREVERSIBLE else: transaction.status = Transaction.Status.PACKED return self
def create_tx(self, actions: List[Action] = None) -> Transaction: """Creates a `Transaction` with default values from this class members. Args: actions: A list of `Actions`. Returns: A `Transaction` object. """ tx = Transaction(gas_limit=self.gas_limit, gas_ratio=self.gas_ratio, expiration=self.expiration, delay=self.delay, actions=actions, chain_id=self.chain_id) tx.add_amount_limit('*', self.default_limit) return tx
def get_tx_by_hash(self, tx_hash: str) -> Transaction: """Gets a `Transaction` by its hash value. Note: REST API: GET "/getTxByHash/{hash}" Args: tx_hash: The base58 hash string of the transaction. Returns: A `Transaction` deserialized from `pb.Transaction`. The status attribute is set with the status code of `pb.TransactionResponse`. """ req = pb.TxHashRequest(hash=tx_hash) res: pb.TransactionResponse = self._stub.GetTxByHash(req) tx = Transaction().from_raw(res.transaction) tx.status = Transaction.Status(res.status) return tx
def sign(self, tx: Transaction, permission: str = 'active') -> Transaction: """Signs a Transaction with a given KeyPair. The Signature will be added to the list of signatures of the transaction. Args: tx: The Transaction to sign, its add_signature method will be called. permission: The KeyPair to use to sign the Transaction. Returns: The Transaction. """ return tx.add_signature(self._kps[permission])
def sign_publish(self, tx: Transaction) -> Transaction: """Signs a Transaction as a publisher. The Signature will be added to the Transaction's publisher signatures. This Account's name will be assigned to the Transaction's publisher. The KeyPair of 'active' permission will be used to sign the Transaction. Args: tx: The Transaction to sign, its add_publisher_signature method will be called. Returns: The Transaction. """ return tx.add_publisher_signature(self.name, self._kps['active'])
def exec_tx(self, tx: Transaction) -> TxReceipt: """Executes a `Transaction` serialized as a `TransactionRequest`. If the `Transaction` has no publisher set, signs it with the default `publisher`. Note: REST API: POST "/execTx" (tx in the body) Args: tx: The `Transaction` to serialize. Returns: The receipt of the transaction as a `TxReceipt` object. """ if tx.publisher is None: if self.publisher is None: raise ValueError('No publisher has signed the transaction.') self.publisher.sign_publish(tx) tr: pb.TxReceipt = self._stub.ExecTransaction(tx.to_request_raw()) return TxReceipt().from_raw(tr)
def send_tx(self, tx: Transaction) -> str: """Sends a `Transaction` serialized as a `TransactionRequest`. If the `Transaction` has no publisher set, signs it with the default `publisher`. Notes: REST API: POST "/sendTx" (tx in the body) Args: tx: The `Transaction` to serialize. Returns: The hash value of the `Transaction` received by the node. """ if tx.publisher == '': if self.publisher is None: raise ValueError('No publisher has signed the transaction.') self.publisher.sign_publish(tx) res: pb.SendTransactionResponse = self._stub.SendTransaction( tx.to_request_raw()) return res.hash
def encode_and_decode(self): tx = Transaction(actions=self.actions, signers=[self.a1.id], gas_limit=100000, gas_ratio=100, expiration=11, delay=0) tx1 = Transaction(actions=[], signers=[], gas_limit=0, gas_ratio=0, expiration=0, delay=0) hash = tx._hash() encoded = tx.encode() self.assertIsNotNone(tx1.decode(encoded)) hash1 = tx1.hash() self.assertEqual(hash, hash1) sig = sign_tx_content(tx, self.a1) self.assertIsNotNone(sig) self.assertIsNotNone(sign_tx(tx, self.a1, sig)) hash = tx.hash() encoded = tx.encode() self.assertIsNotNone(tx1.decode(encoded)) hash1 = tx1.hash() self.assertEqual(hash, hash1) self.assertEqual(tx.time, tx1.time) self.assertEqual(tx.expiration, tx1.expiration) self.assertEqual(tx.gas_limit, tx1.gas_limit) self.assertEqual(tx.gas_price, tx1.gas_price) self.assertEqual(len(tx.actions), len(tx1.actions)) for i in range(len(tx.actions)): self.assertEqual(tx.actions[i].contract, tx1.actions[i].contract) self.assertEqual(tx.actions[i].action_name, tx1.actions[i].action_name) self.assertEqual(tx.actions[i].data, tx1.actions[i].data) self.assertEqual(len(tx.signers), len(tx1.signers)) for i in range(len(tx.signers)): self.assertEqual(tx.signers[i], tx1.signers[i]) self.assertEqual(len(tx.signs), len(tx1.signs)) for i in range(len(tx.actions)): self.assertEqual(tx.signs[i].algorithm, tx1.signs[i].algorithm) self.assertEqual(tx.signs[i].pubkey, tx1.signs[i].pubkey) self.assertEqual(tx.signs[i].sig, tx1.signs[i].sig) self.assertTrue((tx.publisher is None and tx1.publisher is None) or tx.publisher.algorithm == tx1.publisher.algorithm) self.assertTrue((tx.publisher is None and tx1.publisher is None) or tx.publisher.pubkey == tx1.publisher.pubkey) self.assertTrue((tx.publisher is None and tx1.publisher is None) or tx.publisher.sig == tx1.publisher.sig)
def test_sig_and_verify(self): tx = Transaction(self.actions, [self.a1.pubkey, self.a2.pubkey], 9999, 1, 1) sig1 = sign_tx_content(tx, self.a1) self.assertTrue(tx.verify_signer(sig1)) tx.signs.append(sig1) with self.assertRaises(PermissionError) as cm: tx.verify_self() print(cm.exception) sig2 = sign_tx_content(tx, self.a2) self.assertTrue(tx.verify_signer(sig2)) tx.signs.append(sig2) with self.assertRaises(PermissionError) as cm: tx.verify_self() print(cm.exception) with self.assertRaises(PermissionError) as cm: sign_tx_content(tx, self.a3) print(cm.exception) self.assertIsNotNone(sign_tx(tx, self.a3)) self.assertTrue(tx.verify_self()) tx.publisher = Signature(self.algo, b'hello', self.algo.gen_seckey()) with self.assertRaises(PermissionError) as cm: tx.verify_self() print(cm.exception) tx.signs[0] = Signature(self.algo, b'hello', self.algo.gen_seckey()) with self.assertRaises(PermissionError) as cm: tx.verify_self() print(cm.exception)
def test_get_tx_by_hash(self): tx_hash = b'6iYtt5eqwmEcDKfte7FhZFpcVXgsf7CR7wfbm1CqiHZb' tx, res_hash = self.iost.get_tx_by_hash(tx_hash) tx_compare = Transaction() # add content print(tx) self.assertEqual(res_hash, tx_hash)