Skip to main content

Build weiroll transactions with ape

Project description

ape-roll

April O'Neil

ape-roll is a planner for the operation-chaining/scripting language weiroll. ape-roll is inspired by weiroll.js.

It provides an easy-to-use API for generating weiroll programs that can be passed to any compatible implementation.

Installation

pip install ape-roll==0.0.2

where 0.0.2 is the latest version.

Usage

Wrapping contracts

Weiroll programs consist of a sequence of calls to functions in external contracts. These calls can be delegate calls to dedicated library contracts, or standard/static calls to external contracts. Before you can start creating a weiroll program, you must create interfaces for at least one contract you intend to use.

The easiest way to do this is by wrapping ape contract instances:

ape_contract = ape.Contract(address)
contract = ape_roll.WeirollContract(
  ape_contract
)

This will produce a contract object that generates delegate calls to the ape contract in WeirollContract.

To create a delegate to an external contract, use createLibrary:

ape_contract = ape.Contract(address)
# Makes calls using CALL
contract = ape_roll.WeirollContract.createContract(ape_contract)
# Makes calls using STATICCALL
contract = ape_roll.WeirollContract.createLibrary(ape_contract)

You can just repeat this for each contract you'd like to use. A weiroll WeirollContract object can be reused across as many planner instances as you wish; there is no need to construct them again for each new program.

Planning programs

First, instantiate a planner:

planner = ape_roll.WeirollPlanner()

Next, add one or more commands to execute:

ret = planner.add(contract.func(a, b))

Return values from one invocation can be used in another one:

planner.add(contract.func2(ret))

Remember to wrap each call to a contract in planner.add. Attempting to pass the result of one contract function directly to another will not work - each one needs to be added to the planner!

For calls to external contracts, you can also pass a value in ether to send:

planner.add(contract.func(a, b).withValue(c))

withValue takes the same argument types as contract functions so that you can pass the return value of another function or a literal value. You cannot combine withValue with delegate calls (eg, calls to a library created with Contract.newLibrary) or static calls.

Likewise, if you want to make a particular call static, you can use .staticcall():

result = planner.add(contract.func(a, b).staticcall())

Weiroll only supports functions that return a single value by default. If your function returns multiple values, though, you can instruct weiroll to wrap it in a bytes, which subsequent commands can decode and work with:

ret = planner.add(contract.func(a, b).rawValue())

Once you are done planning operations, generate the program:

commands, state = planner.plan()

Subplans

In some cases, it may be useful to instantiate nested instances of the weiroll VM - for example, when using flash loans, or other systems that function by making a callback to your code. The weiroll planner supports this via 'subplans'.

To make a subplan, construct the operations that should take place inside the nested instance usually, then pass the planner object to a contract function that executes the subplan, and pass that to the outer planner's .addSubplan() function instead of .add().

For example, suppose you want to call a nested instance to do some math:

subplanner = WeirollPlanner()
sum = subplanner.add(Math.add(1, 2))

planner = WeirollPlanner()
planner.addSubplan(Weiroll.execute(subplanner, subplanner.state))
planner.add(events.logUint(sum))

commands, state = planner.plan()

Subplan functions must specify which argument receives the current state using the special variable Planner.state and take exactly one subplanner and one state argument. Subplan functions must either return an updated state or nothing.

If a subplan returns an updated state, return values created in a subplanner, such as sum above, can be referenced in the outer scope, and even in other subplans, as long as they are referenced after the command that produces them. Subplans that do not return updated state are read-only, and return values defined inside them cannot be referenced outside them.

More examples

Review tests for more examples.

Credits

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ape-roll-0.0.3.tar.gz (13.8 kB view details)

Uploaded Source

Built Distribution

ape_roll-0.0.3-py3-none-any.whl (12.3 kB view details)

Uploaded Python 3

File details

Details for the file ape-roll-0.0.3.tar.gz.

File metadata

  • Download URL: ape-roll-0.0.3.tar.gz
  • Upload date:
  • Size: 13.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.13 CPython/3.9.17 Darwin/22.6.0

File hashes

Hashes for ape-roll-0.0.3.tar.gz
Algorithm Hash digest
SHA256 2790ce4763cff7ec3e0d97456bc5bd3c74bd026d79c761e51db543df55d56ca1
MD5 872a62c8683eb49bee2303eb7fdbc0c9
BLAKE2b-256 bf3649000a2b9f9bca6d8422f5c055956b2776dc1d422c0569a413c7c64f7c03

See more details on using hashes here.

File details

Details for the file ape_roll-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: ape_roll-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 12.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.13 CPython/3.9.17 Darwin/22.6.0

File hashes

Hashes for ape_roll-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 11030cbe2b8b52e53679dbf73b7738dbe467aa36c7118bc23909c29593f2351e
MD5 d34f78caa6f25534fa85d9ded4951a56
BLAKE2b-256 714ef014d28db11fe4a65a2c0a5004a0a1f94fd206f8c44cf1ddfc38bb32b49b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page