示例#1
0
class BaseParamsBuilder(object):
    def __init__(self, *args, **kwargs):
        self.ms = MemoryStream(*args, **kwargs)

    def set_buffer(self, value: Union[bytes, str]):
        if isinstance(value, str):
            value = bytes.fromhex(value)
        self.ms = MemoryStream(value)

    def clear_up(self):
        self.ms.clean_up()

    def read_byte(self) -> bytes:
        return self.ms.read(1)

    def read_bytes(self, size: int) -> bytes:
        return self.ms.read(size)

    def write_bytes(self, value: bytearray or bytes or str or int):
        if isinstance(value, bytearray) or isinstance(value, bytes):
            self.ms.write(value)
        elif isinstance(value, str):
            self.ms.write(value.encode('utf-8'))
        elif isinstance(value, int):
            self.ms.write(bytes([value]))
        else:
            raise SDKException(ErrorCode.param_err('type error, write byte failed.'))

    def emit(self, op):
        self.write_bytes(op)

    def push_bytearray(self, data: Union[bytes, bytearray]):
        data_len = len(data)
        if data_len < int.from_bytes(PUSHBYTES75, 'little'):
            self.write_bytes(bytearray([data_len]))
        elif data_len < 0x100:
            self.emit(PUSHDATA1)
            self.write_bytes(bytearray([data_len]))
        elif data_len < 0x10000:
            self.emit(PUSHDATA2)
            self.write_bytes(len(data).to_bytes(2, "little"))
        else:
            self.emit(PUSHDATA4)
            self.write_bytes(len(data).to_bytes(4, "little"))
        self.write_bytes(data)

    def to_bytes(self) -> bytes:
        return self.ms.to_bytes()

    def to_bytearray(self) -> bytearray:
        return bytearray(self.ms.to_bytes())
示例#2
0
class ParamsBuilder:
    def __init__(self):
        self.ms = MemoryStream()

    def clear_up(self):
        self.ms.clean_up()

    def emit(self, op):
        self.write_bytes(op)

    def emit_push_bool(self, data: bool):
        if data:
            return self.emit(PUSH1)
        else:
            return self.emit(PUSH0)

    def emit_push_int(self, num: int):
        if num == -1:
            return self.emit(PUSHM1)
        elif num == 0:
            return self.emit(PUSH0)
        elif 0 < num < 16:
            return self.emit(int.from_bytes(PUSH1, 'little') - 1 + num)
        else:
            bs = self.big_int_to_neo_bytearray(num)
            return self.emit_push_bytearray(bs)

    def emit_push_bytearray(self, data):
        data_len = len(data)
        if data_len < int.from_bytes(PUSHBYTES75, 'little'):
            self.write_bytes(bytearray([data_len]))
        elif data_len < 0x100:
            self.emit(PUSHDATA1)
            self.write_bytes(bytearray([data_len]))
        elif data_len < 0x10000:
            self.emit(PUSHDATA2)
            self.write_bytes(len(data).to_bytes(2, "little"))
        else:
            self.emit(PUSHDATA4)
            self.write_bytes(len(data).to_bytes(4, "little"))
        self.write_bytes(data)

    def emit_push_call(self, address):
        self.emit(APPCALL)
        self.write_bytes(address)

    def write_bytes(self, value: bytearray or bytes or str or int):
        if isinstance(value, bytearray) or isinstance(value, bytes):
            self.ms.write(value)
        elif isinstance(value, str):
            self.ms.write(value.encode('utf-8'))
        elif isinstance(value, int):
            self.ms.write(bytes([value]))
        else:
            raise SDKException(ErrorCode.param_err('type error, write byte failed.'))

    @staticmethod
    def int_to_bytearray(data: int):
        bit_length = data.bit_length() // 8
        t = data.bit_length() / 8
        if bit_length <= t:
            bit_length += 1
        return bytearray(data.to_bytes(bit_length, "big", signed=True))

    def big_int_to_neo_bytearray(self, data: int) -> bytearray:
        if data == 0:
            return bytearray()
        data_bytes = self.int_to_bytearray(data)
        if len(data_bytes) == 0:
            return bytearray()
        if data < 0:
            data_bytes2 = self.int_to_bytearray(-data)
            b = data_bytes2[0]
            data_bytes.reverse()
            if b >> 7 == 1:
                res = data_bytes[:] + bytearray([255])
                return res
            return data_bytes
        else:
            b = data_bytes[0]
            data_bytes.reverse()
            if b >> 7 == 1:
                res = data_bytes[:] + bytearray([0])
                return res
            return data_bytes

    def to_bytes(self) -> bytes:
        return self.ms.to_bytes()

    def to_bytearray(self) -> bytearray:
        return bytearray(self.ms.to_bytes())