add simple call

This commit is contained in:
banteg 2020-01-28 16:09:18 +07:00
parent 5c9a6c298a
commit 3dd65ad05f
2 changed files with 49 additions and 0 deletions

27
multicall/call.py Normal file
View File

@ -0,0 +1,27 @@
from dataclasses import dataclass
from eth_utils import to_checksum_address
from web3.auto import w3
from multicall.signature import Signature
class Call:
def __init__(self, target, function, returns):
self.target = to_checksum_address(target)
if isinstance(function, list):
self.function, *self.args = function
else:
self.function = function
self.args = None
self.signature = Signature(self.function)
self.returns = returns
def __call__(self, args=None):
args = args or self.args
calldata = self.signature.encode_data(args)
output = w3.eth.call({'to': self.target, 'data': calldata})
decoded = self.signature.decode_data(output)
return {
name: handler(value) if handler else value
for (name, handler), value
in zip(self.returns, decoded)
}

22
tests/test_call.py Normal file
View File

@ -0,0 +1,22 @@
from multicall.call import Call
CHAI = '0x06AF07097C9Eeb7fD685c692751D5C66dB49c215'
def from_wei(value):
return value / 1e18
def test_call():
call = Call(CHAI, 'name()(string)', [['name', None]])
assert call() == {'name': 'Chai'}
def test_call_with_args():
call = Call(CHAI, 'balanceOf(address)(uint256)', [['balance', from_wei]])
assert isinstance(call([CHAI])['balance'], float)
def test_call_with_predefined_args():
call = Call(CHAI, ['balanceOf(address)(uint256)', CHAI], [['balance', from_wei]])
assert isinstance(call()['balance'], float)