Skip to content

Commit

Permalink
♻️ shanghai upgrades 5 files changed, 57 insertions(+), 9 deletions(-)
Browse files Browse the repository at this point in the history
  • Loading branch information
jjhesk committed Apr 15, 2024
1 parent 0b99dca commit aa25a03
Show file tree
Hide file tree
Showing 14 changed files with 787 additions and 9 deletions.
40 changes: 35 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ It is a all-in-one package with zero setup and configurations that works for mul
- flashbots support
- implementation of contract upgradings
- upgrade contracts for 3 different ways
- Multicall3 interactions


### Examples:

##### Deployment of the new contract:

```
```python
# !/usr/bin/env python
# coding: utf-8
import os
Expand All @@ -82,7 +83,8 @@ meta.deploy("Ori20")

#### BSend add signer
Adding signer using bsend
```

```python
# !/usr/bin/env python
# coding: utf-8
import os
Expand Down Expand Up @@ -113,7 +115,7 @@ expressContract.add_signer(signing_address)
#### Mint Coins
The example for minting coins with 18 decimal

```
```python
# !/usr/bin/env python
# coding: utf-8
import os
Expand Down Expand Up @@ -145,7 +147,7 @@ tokenContract.EnforceTxReceipt(True).mint(my_wallet, 300*10**18)


### Example for compiling contracts with solc
```
```python
# !/usr/bin/env python
# coding: utf-8

Expand Down Expand Up @@ -189,7 +191,7 @@ The new build codebase all in the one take. In order to use this feature, the re
If you are all set, then you are ready to run the following code for example:


```
```python
# !/usr/bin/env python
# coding: utf-8
import os
Expand All @@ -214,7 +216,35 @@ r.useForge().localTranspile()



### Example for multicall

```python

from multicall import Call, Multicall

# assuming you are on kovan
MKR_TOKEN = '0xaaf64bfcc32d0f15873a02163e7e500671a4ffcd'
MKR_WHALE = '0xdb33dfd3d61308c33c63209845dad3e6bfb2c674'
MKR_FISH = '0x2dfcedcb401557354d0cf174876ab17bfd6f4efd'

def from_wei(value):
return value / 1e18

multi = Multicall([
Call(MKR_TOKEN, ['balanceOf(address)(uint256)', MKR_WHALE], [('whale', from_wei)]),
Call(MKR_TOKEN, ['balanceOf(address)(uint256)', MKR_FISH], [('fish', from_wei)]),
Call(MKR_TOKEN, 'totalSupply()(uint256)', [('supply', from_wei)]),
])

multi() # {'whale': 566437.0921992733, 'fish': 7005.0, 'supply': 1000003.1220798912}

# seth-style calls
Call(MKR_TOKEN, ['balanceOf(address)(uint256)', MKR_WHALE])()
Call(MKR_TOKEN, 'balanceOf(address)(uint256)')(MKR_WHALE)
# return values processing
Call(MKR_TOKEN, 'totalSupply()(uint256)', [('supply', from_wei)])()

```
Documentation is ready [here](https://htmlpreview.github.io/?https://github.com/tokenchain/moodyeth/blob/main/docs/moody/index.html)

Also there is a brother library for those who works with [Tron](https://github.com/tokenchain/tronpytool) network.
Expand Down
14 changes: 14 additions & 0 deletions moody/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,20 @@ class Evm:
5 August 2021
The block’s base fee (EIP-3198 and EIP-1559) can be accessed via the global block.basefee or basefee() in inline assembly.
"""
SHANGHAI = "shanghai"
"""
12 Apr 2023
Smaller code size and gas savings due to the introduction of push0
"""
DECUN = "decun"
"""
13 Mar 2024
The block’s blob base fee (EIP-7516 and EIP-4844) can be accessed via the global
block.blobbasefee
or
blobbasefee()
in inline assembly.
"""


class DefaultKeys:
Expand Down
4 changes: 4 additions & 0 deletions moody/buildercompile/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#!/usr/bin/env python
"""
Compiler build for linux system or unix system
"""
REC = """#!/bin/bash
if [[ ! -f {TARGET_LOC} ]]; then
mkdir -p {TARGET_LOC}/vault
Expand Down
3 changes: 3 additions & 0 deletions moody/m/multicall3/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .signature import Signature
from .call import Call
from .multicall import Multicall
151 changes: 151 additions & 0 deletions moody/m/multicall3/call.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
from typing import Any, Callable, Iterable, List, Optional, Tuple, Union

import eth_retry
from eth_typing import Address, ChecksumAddress, HexAddress
from eth_typing.abi import Decodable
from eth_utils import to_checksum_address
from web3 import Web3

from .signature import Signature
from .constants import Network, w3, ASYNC_SEMAPHORE
from .exceptions import StateOverrideNotSupported
from .loggers import setup_logger
from .utils import (chain_id, get_async_w3, run_in_subprocess,
state_override_supported)

logger = setup_logger(__name__)

AnyAddress = Union[str, Address, ChecksumAddress, HexAddress]


class Call:
def __init__(
self,
target: AnyAddress,
function: Union[str, Iterable[Union[str, Any]]],
# 'funcName(dtype)(dtype)' or ['funcName(dtype)(dtype)', input0, input1, ...]
returns: Optional[Iterable[Tuple[str, Callable]]] = None,
block_id: Optional[int] = None,
gas_limit: Optional[int] = None,
state_override_code: Optional[str] = None,
# This needs to be None in order to use process_pool_executor
_w3: Web3 = None
) -> None:
self.target = to_checksum_address(target)
self.returns = returns
self.block_id = block_id
self.gas_limit = gas_limit
self.state_override_code = state_override_code
self.w3 = _w3

self.args: Optional[List[Any]]
if isinstance(function, list):
self.function, *self.args = function
else:
self.function = function
self.args = None

self.signature = Signature(self.function)

def __repr__(self) -> str:
return f'<Call {self.function} on {self.target[:8]}>'

@property
def data(self) -> bytes:
return self.signature.encode_data(self.args)

def decode_output(
output: Decodable,
signature: Signature,
returns: Optional[Iterable[Tuple[str, Callable]]] = None,
success: Optional[bool] = None
) -> Any:

if success is None:
apply_handler = lambda handler, value: handler(value)
else:
apply_handler = lambda handler, value: handler(success, value)

if success is None or success:
try:
decoded = signature.decode_data(output)
except:
success, decoded = False, [None] * (1 if not returns else len(returns)) # type: ignore
else:
decoded = [None] * (1 if not returns else len(returns)) # type: ignore

logger.debug(f'returns: {returns}')
logger.debug(f'decoded: {decoded}')

if returns:
return {
name: apply_handler(handler, value) if handler else value
for (name, handler), value
in zip(returns, decoded)
}
else:
return decoded if len(decoded) > 1 else decoded[0]

@eth_retry.auto_retry
def __call__(self, args: Optional[Any] = None, _w3: Optional[Web3] = None) -> Any:
_w3 = self.w3 or _w3 or w3
args = prep_args(
self.target,
self.signature,
args or self.args,
self.block_id,
self.gas_limit,
self.state_override_code,
)
return Call.decode_output(
_w3.eth.call(*args),
self.signature,
self.returns,
)

def __await__(self) -> Any:
return self.coroutine().__await__()

@eth_retry.auto_retry
async def coroutine(self, args: Optional[Any] = None, _w3: Optional[Web3] = None) -> Any:
_w3 = self.w3 or _w3 or w3

if self.state_override_code and not state_override_supported(_w3):
raise StateOverrideNotSupported(
f'State override is not supported on {Network(chain_id(_w3)).__repr__()[1:-1]}.')

async with ASYNC_SEMAPHORE:
output = await get_async_w3(_w3).eth.call(
*await run_in_subprocess(
prep_args,
self.target,
self.signature,
args or self.args,
self.block_id,
self.gas_limit,
self.state_override_code,
)
)

return await run_in_subprocess(Call.decode_output, output, self.signature, self.returns)


def prep_args(
target: str,
signature: Signature,
args: Optional[Any],
block_id: Optional[int],
gas_limit: int,
state_override_code: str,
) -> List:
calldata = signature.encode_data(args)

args = [{'to': target, 'data': calldata}, block_id]

if gas_limit:
args[0]['gas'] = gas_limit

if state_override_code:
args.append({target: {'code': state_override_code}})

return args
Loading

0 comments on commit aa25a03

Please sign in to comment.