diff --git a/algosdk/future/transaction.py b/algosdk/future/transaction.py
index ce6e283..155826d 100644
--- a/algosdk/future/transaction.py
+++ b/algosdk/future/transaction.py
@@ -703,8 +703,8 @@ class AssetCreateTxn(AssetConfigTxn):
     """
     def __init__(self, sender, sp, total, decimals,
                  default_frozen, *,
-                 manager, reserve, freeze, clawback,
-                 unit_name, asset_name, url,
+                 manager=None, reserve=None, freeze=None, clawback=None,
+                 unit_name="", asset_name="", url="",
                  metadata_hash=None,
                  note=None, lease=None, rekey_to=None):
         super().__init__(sender=sender, sp=sp, total=total, decimals=decimals,
@@ -1151,8 +1151,8 @@ class ApplicationCallTxn(Transaction):
     @staticmethod
     def state_schema(schema):
         """Confirm the argument is a StateSchema, or false which is coerced to None"""
-        if not schema:
-            return None         # Coerce false values to None, to help __eq__
+        if not schema or not schema.dictify():
+            return None         # Coerce false/empty values to None, to help __eq__
         assert isinstance(schema, StateSchema), f"{schema} is not a StateSchema"
         return schema
 
diff --git a/algosdk/v2client/algod.py b/algosdk/v2client/algod.py
index 67c6bd2..322d8fa 100644
--- a/algosdk/v2client/algod.py
+++ b/algosdk/v2client/algod.py
@@ -169,6 +169,8 @@ class AlgodClient:
         Returns:
             str: transaction ID
         """
+        assert not isinstance(txn, future.transaction.Transaction), \
+            f"Attempt to send UNSIGNED transaction {txn}"
         return self.send_raw_transaction(encoding.msgpack_encode(txn),
                                          **kwargs)
 
@@ -243,6 +245,8 @@ class AlgodClient:
         """
         serialized = []
         for txn in txns:
+            assert not isinstance(txn, future.transaction.Transaction), \
+                f"Attempt to send UNSIGNED transaction {txn}"
             serialized.append(base64.b64decode(encoding.msgpack_encode(txn)))
 
         return self.send_raw_transaction(base64.b64encode(

diff --git a/test_unit.py b/test_unit.py
index 7f30d64..a0fa345 100644
--- a/test_unit.py
+++ b/test_unit.py
@@ -852,7 +852,25 @@ class TestApplicationTransactions(unittest.TestCase):
             self.assertEqual(create.dictify(), call.dictify())
             self.assertEqual(create, call)
             self.assertEqual(call, create)
-
+    
+    def test_application_create_schema(self):
+        approve = b"\0"
+        clear = b"\1"
+        zero_schema = transaction.StateSchema(0, 0)
+        params = transaction.SuggestedParams(0, 1, 100, self.genesis)
+        for oc in transaction.OnComplete:
+            # verify that a schema with 0 uints and 0 bytes behaves the same as no schema
+            txn_zero_schema = transaction.ApplicationCreateTxn(self.sender, params, oc,
+                                                      approve, clear,
+                                                      zero_schema, zero_schema)
+            txn_none_schema = transaction.ApplicationCreateTxn(self.sender, params, oc,
+                                                      approve, clear,
+                                                      None, None)
+            # Check the dict first, it's important on it's own, and it
+            # also gives more a meaningful error if they're not equal.
+            self.assertEqual(txn_zero_schema.dictify(), txn_none_schema.dictify())
+            self.assertEqual(txn_zero_schema, txn_none_schema)
+            self.assertEqual(txn_none_schema, txn_zero_schema)
 
     def test_application_update(self):
         empty = b""

Python SDK should detect the meaningless schema and not msgpack it.
If schemas are defined as 0s a signature validation error occurs. This should be checked as described below:

These tests:
        if self.local_schema:
            d["apls"] = self.local_schema.dictify()
        if self.global_schema:
            d["apgs"] = self.global_schema.dictify()
Should be something like if self.schema and not self.schema.empty():
(with empty() defined to return True if both ints and slices are 0)
test_unit.py::TestApplicationTransactions::test_application_create_schema
test_unit.py::TestPaymentTransaction::test_asset_empty_address_error test_unit.py::TestPaymentTransaction::test_asset_transfer_float_amt test_unit.py::TestPaymentTransaction::test_asset_transfer_negative_amt test_unit.py::TestPaymentTransaction::test_error_empty_receiver_asset_txn test_unit.py::TestPaymentTransaction::test_error_empty_receiver_txn test_unit.py::TestPaymentTransaction::test_group_id test_unit.py::TestPaymentTransaction::test_min_txn_fee test_unit.py::TestPaymentTransaction::test_note_wrong_length test_unit.py::TestPaymentTransaction::test_note_wrong_type test_unit.py::TestPaymentTransaction::test_pay_float_amt test_unit.py::TestPaymentTransaction::test_pay_negative_amt test_unit.py::TestPaymentTransaction::test_serialize test_unit.py::TestPaymentTransaction::test_serialize_asset_accept test_unit.py::TestPaymentTransaction::test_serialize_asset_config test_unit.py::TestPaymentTransaction::test_serialize_asset_create test_unit.py::TestPaymentTransaction::test_serialize_asset_create_decimal test_unit.py::TestPaymentTransaction::test_serialize_asset_destroy test_unit.py::TestPaymentTransaction::test_serialize_asset_freeze test_unit.py::TestPaymentTransaction::test_serialize_asset_revoke test_unit.py::TestPaymentTransaction::test_serialize_asset_transfer test_unit.py::TestPaymentTransaction::test_serialize_gen test_unit.py::TestPaymentTransaction::test_serialize_keyreg test_unit.py::TestPaymentTransaction::test_serialize_pay test_unit.py::TestPaymentTransaction::test_serialize_pay_lease test_unit.py::TestPaymentTransaction::test_serialize_txgroup test_unit.py::TestPaymentTransaction::test_serialize_with_note_max_length test_unit.py::TestPaymentTransaction::test_serialize_with_note_string_encode test_unit.py::TestPaymentTransaction::test_serialize_zero_amt test_unit.py::TestPaymentTransaction::test_serialize_zero_receiver test_unit.py::TestPaymentTransaction::test_sign test_unit.py::TestPaymentTransaction::test_sign_logic_multisig test_unit.py::TestAssetConfigConveniences::test_asset_create test_unit.py::TestAssetConfigConveniences::test_asset_destroy test_unit.py::TestAssetConfigConveniences::test_asset_update test_unit.py::TestAssetTransferConveniences::test_asset_closeout test_unit.py::TestAssetTransferConveniences::test_asset_optin test_unit.py::TestApplicationTransactions::test_application_call test_unit.py::TestApplicationTransactions::test_application_create test_unit.py::TestApplicationTransactions::test_application_delete test_unit.py::TestApplicationTransactions::test_application_update test_unit.py::TestMnemonic::test_bytes_wrong_len test_unit.py::TestMnemonic::test_case_irrelevance test_unit.py::TestMnemonic::test_key_wrong_len test_unit.py::TestMnemonic::test_mnemonic_private_key test_unit.py::TestMnemonic::test_mnemonic_wrong_len test_unit.py::TestMnemonic::test_short_words test_unit.py::TestMnemonic::test_whitespace_irrelevance test_unit.py::TestMnemonic::test_word_not_in_list test_unit.py::TestMnemonic::test_wordlist_integrity test_unit.py::TestMnemonic::test_wrong_checksum test_unit.py::TestMnemonic::test_zero_mnemonic test_unit.py::TestAddress::test_encode_decode test_unit.py::TestAddress::test_is_valid test_unit.py::TestMultisig::test_errors test_unit.py::TestMultisig::test_merge test_unit.py::TestMultisig::test_msig_address test_unit.py::TestMultisig::test_sign test_unit.py::TestMsgpack::test_asset_accept test_unit.py::TestMsgpack::test_asset_config test_unit.py::TestMsgpack::test_asset_config_with_decimal test_unit.py::TestMsgpack::test_asset_create test_unit.py::TestMsgpack::test_asset_destroy test_unit.py::TestMsgpack::test_asset_freeze test_unit.py::TestMsgpack::test_asset_revoke test_unit.py::TestMsgpack::test_asset_transfer test_unit.py::TestMsgpack::test_bid test_unit.py::TestMsgpack::test_keyreg_txn test_unit.py::TestMsgpack::test_multisig_txn test_unit.py::TestMsgpack::test_payment_txn test_unit.py::TestMsgpack::test_signed_txn test_unit.py::TestSignBytes::test_sign test_unit.py::TestSignBytes::test_verify_negative test_unit.py::TestLogic::test_check_program test_unit.py::TestLogic::test_parse_bytecblock test_unit.py::TestLogic::test_parse_intcblock test_unit.py::TestLogic::test_parse_uvarint test_unit.py::TestLogic::test_teal_sign test_unit.py::TestLogicSig::test_basic test_unit.py::TestLogicSig::test_multisig test_unit.py::TestLogicSig::test_signature test_unit.py::TestLogicSig::test_transaction test_unit.py::TestTemplate::test_HTLC test_unit.py::TestTemplate::test_dynamic_fee test_unit.py::TestTemplate::test_limit_order_a test_unit.py::TestTemplate::test_periodic_payment test_unit.py::TestTemplate::test_split test_unit.py::TestDryrun::test_create_request test_unit.py::TestDryrun::test_global_state test_unit.py::TestDryrun::test_local_state test_unit.py::TestDryrun::test_no_error test_unit.py::TestDryrun::test_pass_reject