Messing around with signing

This commit is contained in:
Jon Michael Aanes 2025-04-13 12:17:18 +02:00
parent dae2168d8f
commit 9033c8df3d
2 changed files with 30 additions and 13 deletions

View File

@ -55,7 +55,7 @@ def shard_id_for_address(address: str | Address) -> str:
if address is None: if address is None:
msg = 'Address must not be None' msg = 'Address must not be None'
raise TypeError(msg) raise TypeError(msg)
if address.endswith('a'): if address.endswith(('a','d', 'c')):
return 'shards/Shard0/' return 'shards/Shard0/'
if address.endswith('2'): if address.endswith('2'):
return 'shards/Shard1/' return 'shards/Shard1/'
@ -81,7 +81,10 @@ class SenderAuthentication:
return Address(b'\0' + hashed._bytes[-20:]) return Address(b'\0' + hashed._bytes[-20:])
def sign_hash(self, _hash: HashSha256) -> Signature: 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): def _signing_key(self):
secret_exponent = int(self.secret_key, 16) secret_exponent = int(self.secret_key, 16)
@ -102,6 +105,7 @@ def sign_transaction(
contract_address: Address | str, contract_address: Address | str,
transaction_rpc: bytes, transaction_rpc: bytes,
) -> SignedTransaction: ) -> SignedTransaction:
print(contract_address)
sender = sender_authentication.sender_address sender = sender_authentication.sender_address
valid_to_time: int = int(time.time() + TRANSACTION_VALIDITY_DURATION) * 1000 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(Address.from_string(contract_address), transaction_rpc),
) )
transaction_hash_bytes = inner.rpc_serialize() + chain_id.encode('utf8') signature: Signature = sender_authentication.sign_hash(inner.hash(chain_id))
print(signature)
transaction_hash: HashSha256 = HashSha256.of_bytes(transaction_hash_bytes) return SignedTransaction(inner, signature)
signature: Signature = sender_authentication.sign_hash(transaction_hash)
return SignedTransaction(inner, signature, transaction_hash)
@dataclasses.dataclass(frozen=True) @dataclasses.dataclass(frozen=True)
@ -146,6 +148,14 @@ class PbcClient:
rpc, 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) return self.send_signed_transaction(signed_transaction)
def send_signed_transaction(self, signed_transaction: SignedTransaction): def send_signed_transaction(self, signed_transaction: SignedTransaction):
@ -156,9 +166,11 @@ class PbcClient:
), ),
) )
print(signed_transaction)
transaction_payload: str = base64.b64encode( transaction_payload: str = base64.b64encode(
signed_transaction.rpc_serialize(), signed_transaction.rpc_serialize(),
).decode('utf8') ).decode('utf8')
print(transaction_payload)
self._get_json( self._get_json(
url, url,
data={'transactionPayload': transaction_payload}, data={'transactionPayload': transaction_payload},
@ -248,6 +260,7 @@ class PbcClient:
shard=shard_id_for_address(address), shard=shard_id_for_address(address),
address=address, address=address,
) )
print(url)
return self._get_json(url, method='GET')[0]['nonce'] return self._get_json(url, method='GET')[0]['nonce']
def get_contract_state(self, address: str) -> tuple[dict, datetime.datetime]: def get_contract_state(self, address: str) -> tuple[dict, datetime.datetime]:

View File

@ -31,7 +31,7 @@ class Signature:
_bytes: bytes _bytes: bytes
def __post_init__(self): 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: def rpc_serialize(self) -> bytes:
return self._bytes return self._bytes
@ -81,22 +81,26 @@ class SignedTransactionInnerPart:
def rpc_serialize(self) -> bytes: def rpc_serialize(self) -> bytes:
return ( return (
self.nonce.to_bytes(4, 'big') self.nonce.to_bytes(8, 'big')
+ self.valid_to_time.to_bytes(8, 'big') + self.valid_to_time.to_bytes(8, 'big')
+ self.gas_cost.to_bytes(8, 'big') + self.gas_cost.to_bytes(8, 'big')
+ self.transaction.rpc_serialize() + 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) @dataclasses.dataclass(frozen=True)
class SignedTransaction: class SignedTransaction:
inner: SignedTransactionInnerPart inner: SignedTransactionInnerPart
signature: Signature signature: Signature
hash: HashSha256
def hash(self, chain_id: str) -> HashSha256:
return self.inner.hash(chain_id)
def rpc_serialize(self) -> bytes: def rpc_serialize(self) -> bytes:
return ( return (
self.inner.rpc_serialize() self.signature.rpc_serialize()
+ self.signature.rpc_serialize() + self.inner.rpc_serialize()
+ self.hash.rpc_serialize()
) )