Skip to content

Commit

Permalink
Move compile to environment
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielSchiavini committed Apr 17, 2024
1 parent 8c236ab commit 8927cd3
Show file tree
Hide file tree
Showing 10 changed files with 288 additions and 331 deletions.
14 changes: 0 additions & 14 deletions boa_zksync/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
import boa

from boa_zksync.environment import ZksyncEnv
from boa_zksync.interpret import (
compile_zksync,
eval_zksync,
load_zksync,
load_zksync_partial,
loads_zksync,
loads_zksync_partial,
)


def set_zksync_env(url):
Expand All @@ -22,11 +14,5 @@ def set_zksync_browser_env(address=None):
boa.set_env(ZksyncBrowserEnv(address))


boa.compile_zksync = compile_zksync
boa.load_zksync = load_zksync
boa.loads_zksync = loads_zksync
boa.load_zksync_partial = load_zksync_partial
boa.loads_zksync_partial = loads_zksync_partial
boa.eval_zksync = eval_zksync
boa.set_zksync_env = set_zksync_env
boa.set_zksync_browser_env = set_zksync_browser_env
30 changes: 13 additions & 17 deletions boa_zksync/compile.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
import json
import subprocess
from dataclasses import dataclass
from shutil import which
from tempfile import TemporaryDirectory

from boa_zksync.types import ZksyncCompilerData

@dataclass
class ZksyncCompilerData:
"""
Represents the output of the Zksync Vyper compiler (combined_json format).
"""

method_identifiers: dict
abi: list
bytecode: str
bytecode_runtime: str
warnings: list
factory_deps: list


def compile_zksync(file_name: str, compiler_args=None) -> ZksyncCompilerData:
def compile_zksync(filename: str, compiler_args=None) -> ZksyncCompilerData:
vyper_path = which("vyper")
assert vyper_path, "Vyper executable not found"
compile_result = subprocess.run(
Expand All @@ -34,11 +22,19 @@ def compile_zksync(file_name: str, compiler_args=None) -> ZksyncCompilerData:
*(compiler_args or []),
# pass the file name
"--",
file_name,
filename,
],
capture_output=True,
)

assert compile_result.returncode == 0, compile_result.stderr.decode()
output = json.loads(compile_result.stdout.decode())
return ZksyncCompilerData(**output[file_name])
return ZksyncCompilerData(**output[filename])


def compile_zksync_source(source_code: str, name: str, compiler_args=None) -> ZksyncCompilerData:
with TemporaryDirectory() as tempdir:
filename = f"{tempdir}/{name}.vy"
with open(filename, "w") as file:
file.write(source_code)
return compile_zksync(filename, compiler_args)
4 changes: 2 additions & 2 deletions boa_zksync/deployer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
from boa.rpc import to_bytes
from boa.util.abi import Address

from boa_zksync.compile import ZksyncCompilerData
from boa_zksync.environment import ZksyncEnv
from boa_zksync.types import ZksyncCompilerData


class ZksyncDeployer(ABIContractFactory):
Expand All @@ -25,6 +24,7 @@ def __init__(self, compiler_data: ZksyncCompilerData, name: str, filename: str):

def deploy(self, *args, value=0, **kwargs):
env = Env.get_singleton()
from boa_zksync.environment import ZksyncEnv
assert isinstance(
env, ZksyncEnv
), "ZksyncDeployer can only be used in zkSync environments"
Expand Down
81 changes: 27 additions & 54 deletions boa_zksync/environment.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from collections import namedtuple
import logging
from contextlib import contextmanager
from dataclasses import dataclass, field
from functools import cached_property
from hashlib import sha256
from pathlib import Path
Expand All @@ -12,11 +11,13 @@
from boa.network import NetworkEnv, _EstimateGasFailed
from boa.rpc import RPC, EthereumRPC, fixup_dict, to_bytes, to_hex
from boa.util.abi import Address
from boa_zksync.compile import compile_zksync, compile_zksync_source
from eth.constants import ZERO_ADDRESS
from eth.exceptions import VMError

from boa_zksync.deployer import ZksyncDeployer
from boa_zksync.node import EraTestNode
from boa_zksync.util import DeployTransaction
from boa_zksync.types import DeployTransaction, ZksyncComputation, ZksyncMessage

_CONTRACT_DEPLOYER_ADDRESS = "0x0000000000000000000000000000000000008006"
with open(Path(__file__).parent / "IContractDeployer.json") as f:
Expand Down Expand Up @@ -99,24 +100,15 @@ def execute_code(
:param contract: The contract ABI.
:return: The return value of the contract function.
"""
sender = str(self._check_sender(self._get_sender(sender)))
hexdata = to_hex(data)

args = {
"from": sender,
"to": to_address,
"gas": gas,
"value": value,
"data": hexdata,
}
sender = self._check_sender(self._get_sender(sender))
args = ZksyncMessage(sender, to_address, gas or 0, value, data)

if not is_modifying:
output = self._rpc.fetch("eth_call", [fixup_dict(args), "latest"])
output = self._rpc.fetch("eth_call", [args.as_json_dict(), "latest"])
return ZksyncComputation(args, to_bytes(output))

try:
receipt, trace = self._send_txn(
from_=sender, to=to_address, value=value, gas=gas, data=hexdata
)
receipt, trace = self._send_txn(**args.as_tx_params())
except _EstimateGasFailed:
return ZksyncComputation(args, error=VMError("Estimate gas failed"))

Expand Down Expand Up @@ -197,6 +189,24 @@ def deploy_code(
def get_code(self, address):
return self._rpc.fetch("eth_getCode", [address, "latest"])

def create_deployer(
self,
source_code: str,
name: str = None,
filename: str = None,
dedent: bool = True,
compiler_args: dict = None,
) -> "ZksyncDeployer":

if filename:
compiler_data = compile_zksync(filename, compiler_args)
else:
compiler_data = compile_zksync_source(source_code, name, compiler_args)

if not compiler_data.abi:
logging.warning("No ABI found in compiled contract")
return ZksyncDeployer(compiler_data, name or filename, filename=filename)


def _hash_code(bytecode: bytes) -> bytes:
"""
Expand All @@ -209,40 +219,3 @@ def _hash_code(bytecode: bytes) -> bytes:
assert bytecode_size < 2**16, "Bytecode length must be less than 2^16"
bytecode_hash = sha256(bytecode).digest()
return b"\x01\00" + bytecode_size.to_bytes(2, byteorder="big") + bytecode_hash[4:]


@dataclass
class ZksyncComputation:
args: dict
output: bytes | None = None
error: VMError | None = None
children: list["ZksyncComputation"] = field(default_factory=list)

@property
def is_success(self) -> bool:
"""
Return ``True`` if the computation did not result in an error.
"""
return self.error is None

@property
def is_error(self) -> bool:
"""
Return ``True`` if the computation resulted in an error.
"""
return self.error is not None

def raise_if_error(self) -> None:
"""
If there was an error during computation, raise it as an exception immediately.
:raise VMError:
"""
if self.is_error:
raise self.error

@property
def msg(self):
Message = namedtuple('Message', ['sender','to','gas','value','data'])
args = self.args.copy()
return Message(args.pop("from"), data=to_bytes(args.pop("data")), **args)
45 changes: 0 additions & 45 deletions boa_zksync/interpret.py

This file was deleted.

38 changes: 0 additions & 38 deletions boa_zksync/ipython.py

This file was deleted.

Loading

0 comments on commit 8927cd3

Please sign in to comment.