跳转到主要内容

一个Vyper解释器

项目描述

泰坦鳄鱼

一个Vyper解释器,具有漂亮的跟踪回溯、分叉、调试功能等!泰坦鳄鱼的目标是为Vyper用户提供现代、先进且集成的开发体验。

架构

泰坦鳄鱼在功能上与Vyper编译器保持一致,同时提供了解释执行体验。它是如何做到这一点的?在内部,泰坦鳄鱼将Vyper作为库来编译源代码为字节码,然后使用py-evm运行字节码,添加仪器钩子以提供内省。使用py-evm意味着整个体验都是高度可配置的,包括在EVM级别修补操作码和预编译的能力。

文档

使用方法和快速入门指南请见下方。点击此处。如需更详细的文档,请参阅文档

安装

pip install titanoboa

针对最新开发版本

pip install git+https://github.com/vyperlang/titanoboa

如果您在安装 brownie 的同时安装 titanoboa,您可能需要在安装 brownie 之后手动安装 titanoboa

pip install brownie
pip install git+https://github.com/vyperlang/titanoboa

有时,使用pypy可以为计算密集型合约带来显著的性能提升。Pypy通常可以用作CPython的替代品。

为了为主网分叉提供性能提升,请使用forking-recommended扩展安装(使用pip install "git+https://github.com/vyperlang/titanoboa#egg=titanoboa[forking-recommended]"pip install titanoboa[forking-recommended])。这将安装plyvel以在会话之间缓存 RPC 结果,并安装ujson以提高 JSON 性能。

如果您在本地Vyper项目文件夹上运行 titanoboa,如果您遇到如ModuleNotFoundError: No module named 'vyper.version'之类的错误,可能需要运行python setup.py install以在您的Vyper项目上。

背景

Titanoboa (/ˌtaɪtənəˈboʊə/; 直译为“巨大的蟒蛇”)是一个灭绝,是一种巨大的蟒蛇(包括所有蟒蛇和蟒蛇的家族),在中新世晚中新世古近纪时期生活过。Titanoboa 首次在 2000 年代初期由史密森尼热带研究中心发现,该中心与佛罗里达大学的学生一起,在哥伦比亚东北部的瓜希拉发现了 186 具 Titanoboa 化石。它在 2009 年被命名为 Titanoboa cerrejonensis,当时是发现的最大的蛇。最初只知道其胸椎和肋骨,但后来的探险收集到了头骨和牙齿的部分。Titanoboa 属于Boinae亚科,与来自马达加斯加和太平洋的其他现存 boines 关系最密切。

Titanoboa 的长度可达 12.8 米(42 英尺),可能甚至达到 14.3 米(47 英尺),体重约为 730–1,135 公斤(1,610–2,500 磅)。Titanoboa cerrejonensis 的发现取代了之前的记录保持者Gigantophis garstini,后者来自始新世埃及。Titanoboa 在所有非鸟类恐龙灭绝后进化,是白垩纪-古近纪灭绝事件后进化的大型爬行动物之一。其椎骨非常坚固和宽大,从前视图看呈五边形形状,与其他 Boinae 成员相似。尽管最初被认为是一种顶级捕食者,但头骨的发现表明,它更有可能专门捕食鱼类

使用/快速入门

你好,世界

import boa
boa.eval("empty(uint256)")

基础

# simple.vy
@external
def foo() -> uint256:
    x: uint256 = 1
    return x + 7
>>> import boa

>>> simple = boa.load("examples/simple.vy")
>>> simple.foo()
    8
>>> simple.foo()._vyper_type
    uint256

传递__init__

>>> import boa

>>> erc20 = boa.load("examples/ERC20.vy", 'titanoboa', 'boa', 18, 1)
>>> erc20.name()
    titanoboa
>>> erc20.symbol()
    boa
>>> erc20.balanceOf(erc20.address)
    0
>>> erc20.totalSupply()
    1000000000000000000

作为蓝图

>>> import boa
>>> s = boa.load_partial("examples/ERC20.vy")
>>> blueprint = s.deploy_as_blueprint()
>>> deployer = boa.load("examples/deployer.vy", blueprint)
>>> token = s.at(deployer.create_new_erc20("token", "TKN", 18, 10**18))
>>> token.totalSupply()
>>> 1000000000000000000000000000000000000

预期 BoaErrors / 处理回滚

>>> import boa
>>> erc20 = boa.load("examples/ERC20.vy", "titanoboa", "boa", 18, 0)
>>> with boa.env.prank(boa.env.generate_address()):
...     with boa.reverts():
...         erc20.mint(boa.env.eoa, 100)  # non-minter cannot mint
...
>>> with boa.env.prank(boa.env.generate_address()):
...     # you can be more specific about the failure reason
...     with boa.reverts(rekt="non-minter tried to mint"):
...         erc20.mint(boa.env.eoa, 100)

从 IPython 内部运行

In [1]: %load_ext boa.ipython
        import boa
        boa.interpret.set_cache_dir()  # cache source compilations across sessions

In [2]: %vyper msg.sender  # evaluate a vyper expression directly
Out[2]: '0x0000000000000000000000000000000000000065'

In [3]: %%vyper
   ...:
   ...: MY_IMMUTABLE: immutable(uint256)
   ...:
   ...: @external
   ...: def __init__(some_number: uint256):
   ...:     MY_IMMUTABLE = some_number * 2
   ...:
   ...: @external
   ...: def foo() -> uint256:
   ...:     return MY_IMMUTABLE
   ...:
Out[3]: <boa.vyper.contract.VyperDeployer at 0x7f3496187190>

In [4]: d = _

In [4]: c = d.deploy(5)

In [5]: c.foo()
Out[5]: 10

评估任意代码

>>> erc20 = boa.load("examples/ERC20.vy", 'titanoboa', 'boa', 18, 1)
>>> erc20.balanceOf(erc20.address)
    0
>>> erc20.totalSupply()
    1000000000000000000
>>> erc20.eval("self.totalSupply += 10")  # manually mess with total supply
>>> erc20.totalSupply()
1000000000000000010
>>> erc20.eval("self.totalSupply")  # same result when eval'ed
1000000000000000010
>>> erc20.eval("self.balanceOf[msg.sender] += 101")  # manually mess with balance
>>> erc20.balanceOf(boa.env.eoa)
1000000000000000101
>>> erc20.eval("self.balanceOf[msg.sender]")  # same result when eval'ed
1000000000000000101

请注意,在eval()模式下,titanoboa 使用略微不同的优化设置,因此与使用外部接口相比,气体使用可能不同。

分叉

给定 rpc 创建主网的分叉。

In [1]: import boa; boa.env.fork(url="<rpc server address>")

In [2]: %load_ext boa.ipython

In [3]: %%vyper Test
   ...: interface HasName:
   ...:     def name() -> String[32]: view
   ...:
   ...: @external
   ...: def get_name_of(addr: HasName) -> String[32]:
   ...:     return addr.name()
Out[3]: <boa.vyper.contract.VyperDeployer at 0x7f3496187190>

In [4]: c = Test.deploy()

In [5]: c.get_name_of("0xD533a949740bb3306d119CC777fa900bA034cd52")
Out[5]: 'Curve DAO Token'

将当前部署的地址映射到vyper合约

>>> import boa; boa.env.fork(url="<rpc server address>")
>>> c = boa.load_partial("examples/ERC20.vy").at("0xD533a949740bb3306d119CC777fa900bA034cd52")
>>> c.name()
    'Curve DAO Token'

网络模式

>>> import boa
>>> boa.set_network_env("<rpc server address>")
>>> from eth_account import Account
>>> # in a real codebase, always load private keys safely from an encrypted store!
>>> boa.env.add_account(Account.from_key("<a private key>"))
>>> c = boa.load("examples/ERC20.vy", "My Token", "TKN", 10**18, 10)
>>> c.name()
    'My Token'

Jupyter集成

您可以使用Jupyter在网络模式下从浏览器执行titanoboa代码,并使用任何钱包。我们提供了一个BrowserSigner作为eth_account.Account的即插即用替代品。《code>BrowserRPC可以用于从浏览器与RPC服务器交互。

有关完整示例,请参阅此示例Jupyter笔记本

JupyterLab

在使用插件之前,您需要安装它。您可以在终端中运行以下命令来完成此操作

pip install titanoboa
jupyter lab extension enable boa

要激活我们的IPython扩展,您需要在笔记本中运行以下命令

%load_ext boa.ipython

为方便使用,将以下内容添加到ipython_config.py

c.InteractiveShellApp.extensions = ["boa.ipython"]
c.InteractiveShellApp.exec_lines = ['import boa']

我们在try.vyperlang.org上提供了带有JupyterLab的多用户设置,其中已安装并激活了扩展。此网站的源代码可在GitHub仓库中找到。

Colab

您也可以在Google Colab上运行我们的插件。为此,您需要运行以下命令来安装插件

!pip install titanoboa
%load_ext boa.ipython

IPython扩展

这激活了%%vyper%%contract%%eval魔术。

基本测试

$ python -m tests.integration.sim_veYFI

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面