Resolving issues with transaction sending
This commit is contained in:
parent
5021b6c540
commit
c67b838e47
|
@ -41,7 +41,8 @@ URL_NONCE = 'https://{hostname}/{shard}blockchain/account/{address}'
|
|||
MPC_DECIMALS = 10000
|
||||
|
||||
|
||||
def shard_id_for_address(address: str) -> str:
|
||||
def shard_id_for_address(address: str | Address) -> str:
|
||||
address = str(address)
|
||||
# Very rough implementation
|
||||
if address is None:
|
||||
msg = 'Address must not be None'
|
||||
|
@ -64,13 +65,18 @@ class SenderAuthentication:
|
|||
secret_key: str
|
||||
|
||||
def sender_address(self) -> Address:
|
||||
return Address(self._signing_key().verifying_key.to_string())
|
||||
derp = self._signing_key().verifying_key.to_string()
|
||||
hashed = HashSha256.of_bytes(derp)
|
||||
print(derp.hex())
|
||||
print(derp)
|
||||
print(hashed)
|
||||
return Address(b'\0' + hashed._bytes[-20:])
|
||||
|
||||
def sign_hash(self, _hash: HashSha256) -> Signature:
|
||||
return Signature(self._signing_key().sign(_hash.bytes))
|
||||
return Signature(self._signing_key().sign(_hash._bytes))
|
||||
|
||||
def _signing_key(self):
|
||||
return ecdsa.SigningKey.from_string(bytearray.fromhex(self.secret_key), curve=ecdsa.secp256k1)
|
||||
return ecdsa.SigningKey.from_string(bytearray.fromhex(self.secret_key), curve=ecdsa.SECP256k1)
|
||||
|
||||
TRANSACTION_VALIDITY_DURATION = 60
|
||||
|
||||
|
@ -79,7 +85,7 @@ def sign_transaction(
|
|||
nonce: int,
|
||||
gas_cost: int,
|
||||
chain_id: str,
|
||||
contract_address: str,
|
||||
contract_address: Address | str,
|
||||
transaction_rpc: bytes,
|
||||
) -> SignedTransaction:
|
||||
sender = sender_authentication.sender_address
|
||||
|
@ -88,7 +94,7 @@ def sign_transaction(
|
|||
inner: SignedTransactionInnerPart = SignedTransactionInnerPart(nonce,
|
||||
valid_to_time,
|
||||
gas_cost,
|
||||
Transaction(contract_address,
|
||||
Transaction(Address.from_string(contract_address),
|
||||
transaction_rpc))
|
||||
|
||||
transaction_hash_bytes = inner.rpc_serialize() + chain_id.encode('utf8')
|
||||
|
@ -104,6 +110,14 @@ class PbcClient:
|
|||
sender_authentication: SenderAuthentication | None = None
|
||||
hostname: str = HOSTNAME_MAINNET
|
||||
|
||||
def __post_init__(self):
|
||||
assert isinstance(self.session, requests.Session)
|
||||
assert isinstance(self.hostname, str)
|
||||
|
||||
if self.sender_authentication is not None:
|
||||
assert isinstance(self.sender_authentication, SenderAuthentication)
|
||||
|
||||
|
||||
def send_transaction(self, contract_address: str, rpc: bytes, gas_cost: int):
|
||||
if self.sender_authentication is None:
|
||||
msg = "PbcClient.sender_authentication required for send_transaction"
|
||||
|
@ -196,13 +210,13 @@ class PbcClient:
|
|||
return Balances(date, mpc, byoc)
|
||||
|
||||
def get_chain_id(self) -> str:
|
||||
url = URL_NONCE.format(
|
||||
url = URL_CHAIN_ID.format(
|
||||
hostname=self.hostname,
|
||||
)
|
||||
return self._get_json(url, method='GET')[0]['chainId']
|
||||
|
||||
def get_sender_authentication_nonce(self) -> int:
|
||||
return self.get_nonce_for_account(self.sender_authentication.sender_address)
|
||||
return self.get_nonce_for_account(self.sender_authentication.sender_address())
|
||||
|
||||
def get_nonce_for_account(self, address: str) -> int:
|
||||
url = URL_NONCE.format(
|
||||
|
|
|
@ -22,27 +22,40 @@ class Address:
|
|||
_bytes: bytes
|
||||
|
||||
def __post_init__(self):
|
||||
assert len(self._bytes) == 21
|
||||
assert len(self._bytes) == 21, len(self._bytes)
|
||||
|
||||
def rpc_serialize(self) -> bytes:
|
||||
return self._bytes
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self._bytes.hex()
|
||||
|
||||
@staticmethod
|
||||
def from_string(s: str) -> 'Address':
|
||||
if isinstance(s, Address):
|
||||
return s
|
||||
return Address(bytes.fromhex(s))
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class Signature:
|
||||
_bytes: bytes
|
||||
|
||||
def __post_init__(self):
|
||||
assert len(self._bytes) == 32
|
||||
assert len(self._bytes) == 64, len(self._bytes)
|
||||
|
||||
def rpc_serialize(self) -> bytes:
|
||||
return self._bytes
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self._bytes.hex()
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class HashSha256:
|
||||
_bytes: bytes
|
||||
|
||||
def __post_init__(self):
|
||||
assert len(self._bytes) == 32
|
||||
assert len(self._bytes) == 32, len(self._bytes)
|
||||
|
||||
@staticmethod
|
||||
def of_bytes(b: bytes) -> 'HashSha256':
|
||||
|
@ -51,11 +64,17 @@ class HashSha256:
|
|||
def rpc_serialize(self) -> bytes:
|
||||
return self._bytes
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self._bytes.hex()
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class Transaction:
|
||||
contract_address: Address
|
||||
transaction_rpc: bytes
|
||||
|
||||
def __post_init__(self):
|
||||
assert isinstance(self.contract_address, Address), self.contract_address
|
||||
|
||||
def rpc_serialize(self) -> bytes:
|
||||
return self.contract_address.rpc_serialize() + size_prefixed(self.transaction_rpc)
|
||||
|
||||
|
@ -67,7 +86,7 @@ class SignedTransactionInnerPart:
|
|||
transaction: Transaction
|
||||
|
||||
def rpc_serialize(self) -> bytes:
|
||||
return self.nonce.to_bytes(4, 'big') + self.valid_to_time.to_bytes(4, 'big') + self.gas_cost.to_bytes(4, 'big') + self.transaction.rpc_serialize()
|
||||
return self.nonce.to_bytes(4, 'big') + self.valid_to_time.to_bytes(8, 'big') + self.gas_cost.to_bytes(8, 'big') + self.transaction.rpc_serialize()
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class SignedTransaction:
|
||||
|
|
Loading…
Reference in New Issue
Block a user