def method_arguments_opaque_encode(args: List[MethodArgument]) -> bytes: msg = StreamWriter() for arg in args: method_arg = StreamWriter() if isinstance(arg, Uint32Arg): method_arg.write_bytes(b'uint32') method_arg.write_uint16(0) method_arg.write_uint32(arg) elif isinstance(arg, Uint64Arg): method_arg.write_bytes(b'uint64') method_arg.write_uint16(1) method_arg.write_uint64(arg) elif isinstance(arg, StringArg): method_arg.write_bytes(b'string') method_arg.write_uint16(2) method_arg.write_string(arg) elif isinstance(arg, BytesArg): method_arg.write_bytes(b'bytes') method_arg.write_uint16(3) method_arg.write_bytes(arg) else: raise ValueError(f'unsupported MethodArgument type: {type(arg)}') msg.write_bytes(method_arg.get_stream_value()) method_arg.close() res = msg.get_stream_value() msg.close() return res
def test_write_string(self): sw = StreamWriter() value = 'hello' sw.write_string(value) expected = bytes([0x05, 0x00, 0x00, 0x00, ord('h'), ord('e'), ord('l'), ord('l'), ord('o')]) self.assertEqual(9, sw.get_size()) self.assertEqual(expected, sw.get_stream_value()) sw.write_string(value) expected = bytes([0x05, 0x00, 0x00, 0x00, ord('h'), ord('e'), ord('l'), ord('l'), ord('o'), 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, ord('h'), ord('e'), ord('l'), ord('l'), ord('o')]) self.assertEqual(21, sw.get_size()) self.assertEqual(expected, sw.get_stream_value()) sw.close()
def encode_call_method_request(req: CallMethodRequest) -> bytes: # validate inputs if req.protocol_version != 1: raise ValueError( f'expected ProtocolVersion 1, {req.protocol_version} given') if len(req.public_key) != Keys.ED25519_PUBLIC_KEY_SIZE_BYTES: raise ValueError( f'expected PublicKey length {Keys.ED25519_PUBLIC_KEY_SIZE_BYTES}, {len(req.public_key)} given' ) # encode method arguments input_arguments_bytes = method_arguments_opaque_encode(req.input_arguments) # encode network type network_type = network_type_encode(req.network_type) # encode timestamp timestamp_nano = date_to_unix_nano(req.timestamp) # encode eddsa signer eddsa_signer = StreamWriter() eddsa_signer.write_uint16(network_type) eddsa_signer.write_bytes(req.public_key) signer = StreamWriter() signer.write_uint16(0) # eddsa signer signer.write_bytes(eddsa_signer.get_stream_value()) # encode transaction details transaction = StreamWriter() transaction.write_uint32(req.protocol_version) transaction.write_uint32(req.virtual_chain_id) transaction.write_uint64(timestamp_nano) transaction.write_bytes(signer.get_stream_value()) transaction.write_string(req.contract_name) transaction.write_string(req.method_name) transaction.write_bytes(input_arguments_bytes) # encode call method message msg = StreamWriter() msg.write_bytes(transaction.get_stream_value()) res = msg.get_stream_value() eddsa_signer.close() signer.close() transaction.close() msg.close() return res
def encode_send_transaction_request(req: SendTransactionRequest, private_key: bytes): # validate inputs if req.protocol_version != 1: raise ValueError( f'expected ProtocolVersion 1, {req.protocol_version} given') if len(req.public_key) != Keys.ED25519_PUBLIC_KEY_SIZE_BYTES: raise ValueError( f'expected PublicKey length {Keys.ED25519_PUBLIC_KEY_SIZE_BYTES}, {len(req.public_key)} given' ) if len(private_key) != Keys.ED25519_PRIVATE_KEY_SIZE_BYTES: raise ValueError( f'expected PrivateKey length {Keys.ED25519_PUBLIC_KEY_SIZE_BYTES}, {len(private_key)} given' ) # encode method arguments input_arguments_bytes = method_arguments_opaque_encode(req.input_arguments) # encode network type network_type = network_type_encode(req.network_type) # encode timestamp timestamp_nano = date_to_unix_nano(req.timestamp) # encode eddsa signer eddsa_signer = StreamWriter() eddsa_signer.write_uint16(network_type) eddsa_signer.write_bytes(req.public_key) signer = StreamWriter() signer.write_uint16(0) # eddsa signer signer.write_bytes(eddsa_signer.get_stream_value()) # encode transaction details transaction = StreamWriter() transaction.write_uint32(req.protocol_version) transaction.write_uint32(req.virtual_chain_id) transaction.write_uint64(timestamp_nano) transaction.write_bytes(signer.get_stream_value()) transaction.write_string(req.contract_name) transaction.write_string(req.method_name) transaction.write_bytes(input_arguments_bytes) # sign transaction tx_hash = Digest.calc_tx_hash(transaction.get_stream_value()) sig = Signature.sign_ed25519(private_key, tx_hash) # encode signed transaction signed_transaction = StreamWriter() signed_transaction.write_bytes(transaction.get_stream_value()) signed_transaction.write_bytes(sig) # encode send transaction message msg = StreamWriter() msg.write_bytes(signed_transaction.get_stream_value()) res = msg.get_stream_value() eddsa_signer.close() signer.close() transaction.close() signed_transaction.close() msg.close() return res, Digest.generate_tx_id(tx_hash, timestamp_nano)