diff --git a/pbc_client/__init__.py b/pbc_client/__init__.py index e3c7d3b..eaf0892 100644 --- a/pbc_client/__init__.py +++ b/pbc_client/__init__.py @@ -55,7 +55,7 @@ def shard_id_for_address(address: str | Address) -> str: if address is None: msg = 'Address must not be None' raise TypeError(msg) - if address.endswith('a'): + if address.endswith(('a','d', 'c')): return 'shards/Shard0/' if address.endswith('2'): return 'shards/Shard1/' @@ -81,7 +81,10 @@ class SenderAuthentication: return Address(b'\0' + hashed._bytes[-20:]) def sign_hash(self, _hash: HashSha256) -> Signature: - return Signature(self._signing_key().sign(_hash._bytes)) + signing_key = self._signing_key() + signature = signing_key.sign_digest_deterministic(_hash._bytes) + + return Signature(b'\0' + signature) def _signing_key(self): secret_exponent = int(self.secret_key, 16) @@ -102,6 +105,7 @@ def sign_transaction( contract_address: Address | str, transaction_rpc: bytes, ) -> SignedTransaction: + print(contract_address) sender = sender_authentication.sender_address valid_to_time: int = int(time.time() + TRANSACTION_VALIDITY_DURATION) * 1000 @@ -112,11 +116,9 @@ def sign_transaction( Transaction(Address.from_string(contract_address), transaction_rpc), ) - transaction_hash_bytes = inner.rpc_serialize() + chain_id.encode('utf8') - - transaction_hash: HashSha256 = HashSha256.of_bytes(transaction_hash_bytes) - signature: Signature = sender_authentication.sign_hash(transaction_hash) - return SignedTransaction(inner, signature, transaction_hash) + signature: Signature = sender_authentication.sign_hash(inner.hash(chain_id)) + print(signature) + return SignedTransaction(inner, signature) @dataclasses.dataclass(frozen=True) @@ -146,6 +148,14 @@ class PbcClient: rpc, ) + print('RPC', signed_transaction.rpc_serialize()) + print('RPC length', len(signed_transaction.rpc_serialize())) + + assert len(signed_transaction.inner.transaction.rpc_serialize()) == 25 + assert len(signed_transaction.signature.rpc_serialize()) == 65 + assert len(signed_transaction.inner.rpc_serialize()) == 49 + assert len(signed_transaction.rpc_serialize()) == 114 + return self.send_signed_transaction(signed_transaction) def send_signed_transaction(self, signed_transaction: SignedTransaction): @@ -156,9 +166,11 @@ class PbcClient: ), ) + print(signed_transaction) transaction_payload: str = base64.b64encode( signed_transaction.rpc_serialize(), ).decode('utf8') + print(transaction_payload) self._get_json( url, data={'transactionPayload': transaction_payload}, @@ -248,6 +260,7 @@ class PbcClient: shard=shard_id_for_address(address), address=address, ) + print(url) return self._get_json(url, method='GET')[0]['nonce'] def get_contract_state(self, address: str) -> tuple[dict, datetime.datetime]: diff --git a/pbc_client/pbc_types.py b/pbc_client/pbc_types.py index b6941d6..392cae9 100644 --- a/pbc_client/pbc_types.py +++ b/pbc_client/pbc_types.py @@ -31,7 +31,7 @@ class Signature: _bytes: bytes def __post_init__(self): - assert len(self._bytes) == 64, len(self._bytes) + assert len(self._bytes) == 65, len(self._bytes) def rpc_serialize(self) -> bytes: return self._bytes @@ -81,22 +81,26 @@ class SignedTransactionInnerPart: def rpc_serialize(self) -> bytes: return ( - self.nonce.to_bytes(4, 'big') + self.nonce.to_bytes(8, 'big') + self.valid_to_time.to_bytes(8, 'big') + self.gas_cost.to_bytes(8, 'big') + self.transaction.rpc_serialize() ) + def hash(self, chain_id: str) -> HashSha256: + return HashSha256.of_bytes(self.rpc_serialize() + chain_id.encode('utf8')) + @dataclasses.dataclass(frozen=True) class SignedTransaction: inner: SignedTransactionInnerPart signature: Signature - hash: HashSha256 + + def hash(self, chain_id: str) -> HashSha256: + return self.inner.hash(chain_id) def rpc_serialize(self) -> bytes: return ( - self.inner.rpc_serialize() - + self.signature.rpc_serialize() - + self.hash.rpc_serialize() + self.signature.rpc_serialize() + + self.inner.rpc_serialize() )