You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: withdraw.rs
    path of file: ./repos/bazuka/src/blockchain/ops/apply_tx/update_contract
    
    the code of the file until where you have to start completion: use super::*;

pub fn withdraw<K: KvStore>(
    chain: &mut KvStoreChain<K>,
    contract_id: &ContractId,
    contract: &zk::ZkContract,
    withdraw_circuit_id: &u32,
    withdraws: &[ContractWithdraw],
    executor_fees: &mut Vec<Money>,
) -> Result<(zk::ZkVerifierKey, zk::ZkCompressedState), BlockchainError> {
    let withdraw_func = contract
        .withdraw_functions
        .get(*withdraw_circuit_id as usize)
        .ok_or(BlockchainError::ContractFunctionNotFound)?;
    let circuit = &withdraw_func.verifier_key;
    let state_model = zk::ZkStateModel::List {
        item_type: Box::new(zk::ZkStateModel::Struct {
            field_types: vec![
                zk::ZkStateModel::Scalar, // Enabled
                zk::ZkStateModel::Scalar, // Amount token-id
                zk::ZkStateModel::Scalar, // Amount
                zk::ZkStateModel::Scalar, // Fee token-id
                zk::ZkStateModel::Scalar, // Fee
                zk::ZkStateModel::Scalar, // Fingerprint
                zk::ZkStateModel::Scalar, // Calldata
            ],
        }),
  
    
    fn test_single_withdraw() {
        let mut chain = KvStoreChain::new(
            RamKvStore::new(),
            crate::config::blockchain::get_test_blockchain_config(),
        )
        .unwrap();

        let contract_id = chain.config.mpn_config.mpn_contract_id;

        let abc = TxBuilder::new(&Vec::from("ABC"));
        let mut cont_deposit = ContractDeposit {
            memo: "".into(),
            src: abc.get_address(),
            contract_id,
            deposit_circuit_id: 0,
            calldata: zk::ZkScalar::from(888),
            nonce: 1,
            amount: Money::ziesha(1000),
            fee: Money::ziesha(0),
            sig: None,
        };
        abc.sign_deposit(&mut cont_deposit);
        chain.apply_deposit(&cont_deposit).unwrap();

        let cont_withdraw = ContractWithdraw {
            memo: "".into(),
            contract_id,
            withdraw_circuit_id: 0,
            calldata: zk::ZkScalar::from(777),
            dst: abc.get_address(),
            amount: Money::ziesha(200),
            fee: Money::ziesha(50),
        };

        let (ops, ((_, aux_data), exec_fees)) = chain
            .isolated(|chain| {
                let mut exec_fees = Vec::new();
                let contract = chain.get_contract(contract_id)?;
                Ok((
                    withdraw(
                        chain,
                        &contract_id,
                        &contract,
                        &0,
                        &[cont_withdraw.clone()],
                        &mut exec_fees,
                    )?,
                    exec_fees,
                ))
            })
            .unwrap();
        let empty_leaf =
            <crate::core::ZkHasher as crate::zk::ZkHasher>::hash(&[zk::ZkScalar::from(0); 7]);

        let expected_hash = <crate::core::ZkHasher as crate::zk::ZkHasher>::hash(&[
            <crate::core::ZkHasher as crate::zk::ZkHasher>::hash(&[
                zk::ZkScalar::from(1),
                zk::ZkScalar::from(1),
                zk::ZkScalar::from(200),
                zk::ZkScalar::from(1),
                zk::ZkScalar::from(50),
                zk::ZkScalar::from(cont_withdraw.fingerprint()),
                zk::ZkScalar::from(777),
            ]),
            empty_leaf,
            empty_leaf,
            empty_leaf,
        ]);

        let expected_aux = zk::ZkCompressedState {
            state_hash: expected_hash,
            state_size: 7,
        };

        assert_eq!(aux_data, expected_aux);

        let expected_ops = vec![
            WriteOp::Put(
                "ACB-ed8c19c6a4cf1460e961f7bae8eea54d437b9edac27cbeb09be32ae367adf9098a-Ziesha"
                    .into(),
                Amount(9200).into(),
            ),
            WriteOp::Put(
                "CAB-0x069c7585c9cd138dd714b36716efdff2257e536b3360da2aad96c35c9c46bd5e-Ziesha"
                    .into(),
                Amount(750).into(),
            ),
        ];

        assert_eq!(ops, expected_ops);
        assert_eq!(
            exec_fees,
            vec![Money {
                token_id: ContractId::Ziesha,
                amount: Amount(50)
            }]
        );
    }