anvil_zksync/
bytecode_override.rs1use anvil_zksync_core::node::InMemoryNode;
2use anyhow::Context;
3use hex::FromHex;
4use serde::Deserialize;
5use std::str::FromStr;
6use tokio::fs;
7use zksync_types::Address;
8
9#[derive(Debug, Deserialize)]
10struct ContractJson {
11 bytecode: Bytecode,
12}
13
14#[derive(Debug, Deserialize)]
15struct Bytecode {
16 object: String,
17}
18
19pub async fn override_bytecodes(node: &InMemoryNode, bytecodes_dir: String) -> anyhow::Result<()> {
22 let mut read_dir = fs::read_dir(bytecodes_dir).await?;
23 while let Some(entry) = read_dir.next_entry().await? {
24 let path = entry.path();
25
26 if path.is_file() {
27 let filename = match path.file_name().and_then(|name| name.to_str()) {
28 Some(name) => name,
29 None => anyhow::bail!("Invalid filename {}", path.display().to_string()),
30 };
31
32 if let Some(filename) = filename.strip_suffix(".json") {
34 let address = Address::from_str(filename)
35 .with_context(|| format!("Cannot parse {} as address", filename))?;
36
37 let file_content = fs::read_to_string(&path).await?;
38 let contract: ContractJson = serde_json::from_str(&file_content)
39 .with_context(|| format!("Failed to parse json file {:?}", path))?;
40
41 let bytecode = Vec::from_hex(contract.bytecode.object)
42 .with_context(|| format!("Failed to parse hex from {:?}", path))?;
43
44 node.override_bytecode(address, bytecode)
45 .await
46 .expect("Failed to override bytecode");
47 tracing::debug!("Replacing bytecode at address {:?}", address);
48 }
49 }
50 }
51 Ok(())
52}