def get_context(engine: contracts.ApplicationEngine) -> storage.StorageContext: contract = engine.snapshot.contracts.try_get(engine.current_scripthash, read_only=True) if not contract.has_storage: raise ValueError( "Cannot get context for smart contract without storage") return storage.StorageContext(engine.current_scripthash, False)
def test_storage_put_overwrite(self): # test with new data being shorter than the old data engine = test_engine(has_snapshot=True) key = b'\x01' storage_key = storage.StorageKey(types.UInt160.zero(), key) storage_item = storage.StorageItem(b'\x11\x22\x33', is_constant=False) engine.snapshot.storages.put(storage_key, storage_item) ctx = storage.StorageContext(types.UInt160.zero(), is_read_only=False) new_item_value = b'\x11\x22' contracts.interop._storage_put_internal(engine, ctx, key, new_item_value, storage.StorageFlags.NONE) item = engine.snapshot.storages.get(storage_key) self.assertIsNotNone(item) self.assertEqual(new_item_value, item.value) # now test with data being longer than before longer_item_value = b'\x11\x22\x33\x44' contracts.interop._storage_put_internal(engine, ctx, key, longer_item_value, storage.StorageFlags.NONE) item = engine.snapshot.storages.get(storage_key) self.assertIsNotNone(item) self.assertEqual(longer_item_value, item.value)
def get_read_only_context( engine: contracts.ApplicationEngine) -> storage.StorageContext: contract = contracts.ManagementContract().get_contract( engine.snapshot, engine.current_scripthash) if contract is None: raise ValueError("Contract not deployed") return storage.StorageContext(contract.id, True)
def test_storage_put_helper_parameter_validation(self): with self.assertRaises(ValueError) as context: key = (b'\x01' * contracts.interop.MAX_STORAGE_KEY_SIZE) + b'\x01' contracts.interop._storage_put_internal(None, None, key, b'', None) self.assertEqual( f"Storage key length exceeds maximum of {contracts.interop.MAX_STORAGE_KEY_SIZE}", str(context.exception)) with self.assertRaises(ValueError) as context: value = (b'\x01' * contracts.interop.MAX_STORAGE_VALUE_SIZE) + b'\x01' contracts.interop._storage_put_internal(None, None, b'', value, None) self.assertEqual( f"Storage value length exceeds maximum of {contracts.interop.MAX_STORAGE_VALUE_SIZE}", str(context.exception)) with self.assertRaises(ValueError) as context: ctx = storage.StorageContext(None, is_read_only=True) contracts.interop._storage_put_internal(None, ctx, b'', b'', None) self.assertEqual("Cannot persist to read-only storage context", str(context.exception)) # finaly make sure it fails if we try to modify an item that is marked constant engine = test_engine(has_snapshot=True) key = storage.StorageKey(types.UInt160.zero(), b'\x01') item = storage.StorageItem(b'', is_constant=True) engine.snapshot.storages.put(key, item) with self.assertRaises(ValueError) as context: ctx = storage.StorageContext(types.UInt160.zero(), is_read_only=False) contracts.interop._storage_put_internal(engine, ctx, b'\x01', b'', storage.StorageFlags.NONE) self.assertEqual("StorageItem is marked as constant", str(context.exception))
def test_storage_put_helper_parameter_validation(self): with self.assertRaises(ValueError) as context: key = (b'\x01' * contracts.interop.MAX_STORAGE_KEY_SIZE) + b'\x01' contracts.interop.storage_put(None, None, key, b'') self.assertEqual( f"Storage key length exceeds maximum of {contracts.interop.MAX_STORAGE_KEY_SIZE}", str(context.exception)) with self.assertRaises(ValueError) as context: value = (b'\x01' * contracts.interop.MAX_STORAGE_VALUE_SIZE) + b'\x01' contracts.interop.storage_put(None, None, b'', value) self.assertEqual( f"Storage value length exceeds maximum of {contracts.interop.MAX_STORAGE_VALUE_SIZE}", str(context.exception)) with self.assertRaises(ValueError) as context: ctx = storage.StorageContext(None, is_read_only=True) contracts.interop.storage_put(None, ctx, b'', b'') self.assertEqual("Cannot persist to read-only storage context", str(context.exception))
def context_as_read_only( engine: contracts.ApplicationEngine, context: storage.StorageContext) -> storage.StorageContext: if not context.is_read_only: context = storage.StorageContext(context.script_hash, True) return context