Skip to content

Commit

Permalink
Merge branch 'master' of github.com:vyperlang/titanoboa into vvm-storage
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielSchiavini committed Oct 3, 2024
2 parents 28e97cd + 7f1c700 commit 7837fdb
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 16 deletions.
39 changes: 38 additions & 1 deletion boa/contracts/vvm/vvm_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
from boa.environment import Env
from boa.rpc import to_bytes
from boa.util.abi import Address
from boa.util.eip5202 import generate_blueprint_bytecode


class VVMDeployer(ABIContractFactory):
"""
A factory which can be used to create a new contract deployed with vvm.
A deployer that uses the Vyper Version Manager (VVM).
This allows deployment of contracts written in older versions of Vyper that
can interact with new versions using the ABI definition.
"""

def __init__(
Expand All @@ -25,6 +28,14 @@ def __init__(
vyper_version: str,
filename: Optional[str] = None,
):
"""
Initialize a VVMDeployer instance.
:param name: The name of the contract.
:param compiler_output: The compiler output of the contract.
:param source_code: The source code of the contract.
:param vyper_version: The Vyper version used to compile the contract.
:param filename: The filename of the contract.
"""
super().__init__(name, compiler_output["abi"], filename)
self.compiler_output = compiler_output
self.source_code = source_code
Expand Down Expand Up @@ -68,6 +79,32 @@ def deploy(self, *args, env=None):

return self.at(address)

@cached_property
def _blueprint_bytecode(self):
return generate_blueprint_bytecode(self.bytecode)

@cached_property
def _blueprint_deployer(self):
# TODO: add filename
return ABIContractFactory.from_abi_dict([])

def deploy_as_blueprint(self, env=None, blueprint_preamble=None, **kwargs):
"""
Deploy a new blueprint from this contract.
:param blueprint_preamble: The preamble to use for the blueprint.
:param env: The environment to deploy the blueprint in.
:param kwargs: Keyword arguments to pass to the environment `deploy_code` method.
:returns: A contract instance.
"""
if env is None:
env = Env.get_singleton()

address, _ = env.deploy_code(bytecode=self._blueprint_bytecode)

ret = self._blueprint_deployer.at(address)
env.register_blueprint(self.bytecode, ret)
return ret

def __call__(self, *args, **kwargs):
return self.deploy(*args, **kwargs)

Expand Down
16 changes: 5 additions & 11 deletions boa/contracts/vyper/vyper_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
from boa.environment import Env
from boa.profiling import cache_gas_used_for_computation
from boa.util.abi import Address, abi_decode, abi_encode
from boa.util.eip5202 import generate_blueprint_bytecode
from boa.util.lrudict import lrudict
from boa.vm.gas_meters import ProfilingGasMeter
from boa.vm.utils import to_bytes, to_int
Expand Down Expand Up @@ -183,24 +184,17 @@ def __init__(
compiler_data,
env=None,
override_address=None,
blueprint_preamble=b"\xFE\x71\x00",
blueprint_preamble=None,
filename=None,
gas=None,
):
# note slight code duplication with VyperContract ctor,
# maybe use common base class?
super().__init__(compiler_data, env, filename)

if blueprint_preamble is None:
blueprint_preamble = b""

blueprint_bytecode = blueprint_preamble + compiler_data.bytecode

# the length of the deployed code in bytes
len_bytes = len(blueprint_bytecode).to_bytes(2, "big")
deploy_bytecode = b"\x61" + len_bytes + b"\x3d\x81\x60\x0a\x3d\x39\xf3"

deploy_bytecode += blueprint_bytecode
deploy_bytecode = generate_blueprint_bytecode(
compiler_data.bytecode, blueprint_preamble
)

addr, computation = self.env.deploy(
bytecode=deploy_bytecode, override_address=override_address, gas=gas
Expand Down
17 changes: 17 additions & 0 deletions boa/util/eip5202.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@
from eth_utils import to_canonical_address, to_checksum_address
from vyper.utils import keccak256

DEFAULT_BLUEPRINT_PREAMBLE = b"\xFE\x71\x00"


def generate_blueprint_bytecode(
contract_bytecode: bytes, blueprint_preamble: bytes = None
):
if blueprint_preamble is None:
blueprint_preamble = DEFAULT_BLUEPRINT_PREAMBLE

blueprint_bytecode = blueprint_preamble + contract_bytecode

# the length of the deployed code in bytes
len_bytes = len(blueprint_bytecode).to_bytes(2, "big")
deploy_bytecode = b"\x61" + len_bytes + b"\x3d\x81\x60\x0a\x3d\x39\xf3"

return deploy_bytecode + blueprint_bytecode


# TODO replace return type with upcoming AddressType wrapper
def get_create2_address(
Expand Down
30 changes: 26 additions & 4 deletions tests/unitary/test_blueprints.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,45 @@
import pytest
import vyper
from eth_utils import to_canonical_address

import boa
from boa.util.eip5202 import get_create2_address

blueprint_code = """
_blueprint_code = """
# pragma version {}
@external
def some_function() -> uint256:
return 5
"""

factory_code = """
_factory_code = """
# pragma version {}
@external
def create_child(blueprint: address, salt: bytes32) -> address:
return create_from_blueprint(blueprint, code_offset=3, salt=salt)
"""

VERSIONS = [vyper.__version__, "0.3.10"]


@pytest.fixture(params=VERSIONS)
def version(request):
return request.param


@pytest.fixture
def blueprint_code(version):
return _blueprint_code.format(version)


@pytest.fixture
def factory_code(version):
return _factory_code.format(version)


def test_create2_address():
def test_create2_address(blueprint_code, factory_code):
blueprint = boa.loads_partial(blueprint_code).deploy_as_blueprint()
factory = boa.loads(factory_code)

Expand All @@ -31,7 +53,7 @@ def test_create2_address():
)


def test_create2_address_bad_salt():
def test_create2_address_bad_salt(blueprint_code):
blueprint = boa.loads_partial(blueprint_code).deploy_as_blueprint()
blueprint_bytecode = boa.env.get_code(to_canonical_address(blueprint.address))
with pytest.raises(ValueError) as e:
Expand Down

0 comments on commit 7837fdb

Please sign in to comment.