216 lines
4.5 KiB
Python
216 lines
4.5 KiB
Python
'''
|
|
Definitions of several useful types commonly seen on Partisia Blockchain.
|
|
|
|
Follows the ABI specification quite closely. The full ABI specification can be found at:
|
|
|
|
https://partisiablockchain.gitlab.io/documentation/abiv.html
|
|
'''
|
|
|
|
import datetime
|
|
import dataclasses
|
|
from typing import Mapping, Collection, Optional, Union
|
|
from enum import Enum
|
|
import enforce_typing
|
|
from .binaryreader import BinaryReader
|
|
|
|
def hexformat(bts: bytes, sep=''):
|
|
return sep.join('{:02X}'.format(c) for c in bts)
|
|
|
|
class AddressType(Enum):
|
|
'''
|
|
Type of a PBC BlockchainAddress.
|
|
'''
|
|
ACCOUNT = 0x00
|
|
CONTRACT_SYSTEM = 0x01
|
|
CONTRACT_PUBLIC = 0x02
|
|
CONTRACT_ZK = 0x03
|
|
CONTRACT_GOVERANCE = 0x04
|
|
|
|
def human_name(self):
|
|
'''
|
|
Produces a human-readable name for self.
|
|
'''
|
|
return ADDRESS_TYPES[self]
|
|
|
|
|
|
ADDRESS_TYPES = {
|
|
AddressType.ACCOUNT: 'Account',
|
|
AddressType.CONTRACT_SYSTEM: 'System Contract',
|
|
AddressType.CONTRACT_PUBLIC: 'Public Contract',
|
|
AddressType.CONTRACT_ZK: 'ZK Contract',
|
|
AddressType.CONTRACT_GOVERANCE: 'Governance Contract',
|
|
}
|
|
|
|
|
|
@enforce_typing.enforce_types
|
|
@dataclasses.dataclass(frozen=True, order=True)
|
|
class ByteData(object):
|
|
'''
|
|
Supertype for several built-in PBC types.
|
|
'''
|
|
data: bytes
|
|
|
|
def to_hex(self):
|
|
'''
|
|
Formats this byte data as a hex string.
|
|
'''
|
|
return hexformat(self.data)
|
|
|
|
def short_str(self):
|
|
'''
|
|
Formats this byte data as a short hex string.
|
|
'''
|
|
long = str(self)
|
|
return '{}..{}'.format(long[:4], long[-4:])
|
|
|
|
|
|
@enforce_typing.enforce_types
|
|
@dataclasses.dataclass(frozen=True, order=True)
|
|
class BlockchainAddress(ByteData):
|
|
'''
|
|
Address on PBC.
|
|
'''
|
|
|
|
BYTE_LEN = 21
|
|
|
|
def __post_init__(self):
|
|
assert len(self.data) == BlockchainAddress.BYTE_LEN
|
|
assert self.type()
|
|
|
|
@staticmethod
|
|
def read_from(reader):
|
|
return BlockchainAddress(reader.readBytes(BlockchainAddress.BYTE_LEN))
|
|
|
|
@staticmethod
|
|
def from_hex_hash(s):
|
|
return BlockchainAddress(bytes.fromhex(s))
|
|
|
|
def type(self) -> AddressType:
|
|
return AddressType(self.data[0])
|
|
|
|
def __repr__(self):
|
|
return self.to_hex()
|
|
|
|
def __str__(self):
|
|
return repr(self)
|
|
|
|
def shard_id(self, num_shards: int) -> str:
|
|
reader = BinaryReader(self.data)
|
|
reader.readBytes(17)
|
|
shard = reader.readUInt32BigEndian()
|
|
shard = abs(shard) % num_shards
|
|
return f'Shard{shard}'
|
|
|
|
@enforce_typing.enforce_types
|
|
@dataclasses.dataclass(frozen=True, order=True)
|
|
class Hash(ByteData):
|
|
'''
|
|
Hash.
|
|
'''
|
|
|
|
data: bytes
|
|
|
|
BYTE_LEN = 32
|
|
|
|
@staticmethod
|
|
def read_from(reader):
|
|
return Hash(reader.readBytes(Hash.BYTE_LEN))
|
|
|
|
@classmethod
|
|
def from_hex(cls, s):
|
|
return Hash(bytes.fromhex(s))
|
|
|
|
def __repr__(self):
|
|
return self.to_hex()
|
|
|
|
def __str__(self):
|
|
return repr(self)
|
|
|
|
|
|
@enforce_typing.enforce_types
|
|
@dataclasses.dataclass(frozen=True, order=True)
|
|
class PublicKey(ByteData):
|
|
'''
|
|
PBC public key.
|
|
'''
|
|
|
|
data: bytes
|
|
|
|
BYTE_LEN = 33
|
|
|
|
@staticmethod
|
|
def read_from(reader):
|
|
return PublicKey(reader.readBytes(PublicKey.BYTE_LEN))
|
|
|
|
def __repr__(self):
|
|
return self.to_hex()
|
|
|
|
def __str__(self):
|
|
return repr(self)
|
|
|
|
|
|
@enforce_typing.enforce_types
|
|
@dataclasses.dataclass(frozen=True, order=True)
|
|
class Signature(ByteData):
|
|
'''
|
|
Message signature on PBC.
|
|
'''
|
|
|
|
data: bytes
|
|
|
|
BYTE_LEN = 65
|
|
|
|
@staticmethod
|
|
def read_from(reader):
|
|
return Signature(reader.readBytes(Signature.BYTE_LEN))
|
|
|
|
def __repr__(self):
|
|
return self.to_hex()
|
|
|
|
def __str__(self):
|
|
return repr(self)
|
|
|
|
|
|
@enforce_typing.enforce_types
|
|
@dataclasses.dataclass(frozen=True, order=True)
|
|
class BlsPublicKey(ByteData):
|
|
'''
|
|
BLS Public Key.
|
|
'''
|
|
|
|
data: bytes
|
|
|
|
BYTE_LEN = 96
|
|
|
|
@staticmethod
|
|
def read_from(reader):
|
|
return BlsPublicKey(reader.readBytes(BlsPublicKey.BYTE_LEN))
|
|
|
|
def __repr__(self):
|
|
return self.to_hex()
|
|
|
|
def __str__(self):
|
|
return repr(self)
|
|
|
|
|
|
@enforce_typing.enforce_types
|
|
@dataclasses.dataclass(frozen=True, order=True)
|
|
class BlsSignature(ByteData):
|
|
'''
|
|
BLS signature.
|
|
'''
|
|
|
|
data: bytes
|
|
|
|
BYTE_LEN = 48
|
|
|
|
@staticmethod
|
|
def read_from(reader):
|
|
return BlsSignature(reader.readBytes(BlsSignature.BYTE_LEN))
|
|
|
|
def __repr__(self):
|
|
return self.to_hex()
|
|
|
|
def __str__(self):
|
|
return repr(self)
|