commit c3985236a2aa1f3047b7560a7c200f020e8bcce1
Author: nolash <dev@holbrook.no>
Date: Sun, 2 May 2021 16:30:21 +0200
Initial commit
Diffstat:
10 files changed, 182 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,5 @@
+__pycache__
+build/
+dist/
+*.pyc
+gmon.out
diff --git a/python/eth_interface/__init__.py b/python/eth_interface/__init__.py
@@ -0,0 +1 @@
+from .eip165 import EIP165
diff --git a/python/eth_interface/eip165.py b/python/eth_interface/eip165.py
@@ -0,0 +1,36 @@
+# external imports
+from chainlib.eth.constant import ZERO_ADDRESS
+from chainlib.jsonrpc import (
+ jsonrpc_template,
+ )
+from hexathon import (
+ add_0x,
+ )
+from chainlib.eth.contract import (
+ ABIContractEncoder,
+ ABIContractDecoder,
+ ABIContractType,
+ abi_decode_single,
+ )
+from chainlib.eth.tx import TxFactory
+
+
+class EIP165(TxFactory):
+
+ def supports_interface(self, contract_address, interface_sum, sender_address=ZERO_ADDRESS):
+ o = jsonrpc_template()
+ o['method'] = 'eth_call'
+ enc = ABIContractEncoder()
+ enc.method('supportsInterface')
+ enc.typ(ABIContractType.BYTES4)
+ enc.bytes4(interface_sum)
+ data = add_0x(enc.get())
+ tx = self.template(sender_address, contract_address)
+ tx = self.set_code(tx, data)
+ o['params'].append(self.normalize(tx))
+ return o
+
+
+ @classmethod
+ def parse_supports_interface(self, v):
+ return abi_decode_single(ABIContractType.BOOLEAN, v)
diff --git a/python/requirements.txt b/python/requirements.txt
@@ -0,0 +1 @@
+chainlib~=0.0.3a1
diff --git a/python/setup.cfg b/python/setup.cfg
@@ -0,0 +1,31 @@
+[metadata]
+name = eth-interface
+version = 0.0.1a1
+description = EIP165 interface
+author = Louis Holbrook
+author_email = dev@holbrook.no
+url = https://gitlab.com/nolash/eth-interface
+keywords =
+ ethereum
+classifiers =
+ Programming Language :: Python :: 3
+ Operating System :: OS Independent
+ Development Status :: 3 - Alpha
+ Environment :: No Input/Output (Daemon)
+ Intended Audience :: Developers
+ License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
+ Topic :: Internet
+ #Topic :: Blockchain :: EVM
+license = GPL3
+licence_files =
+ LICENSE
+
+[options]
+include_package_data = True
+python_requires = >= 3.6
+packages =
+ eth-interface
+
+[options.package_data]
+* =
+ data/EIP165.json
diff --git a/python/setup.py b/python/setup.py
@@ -0,0 +1,31 @@
+from setuptools import setup
+
+requirements = []
+f = open('requirements.txt', 'r')
+while True:
+ l = f.readline()
+ if l == '':
+ break
+ requirements.append(l.rstrip())
+f.close()
+
+test_requirements = []
+f = open('test_requirements.txt', 'r')
+while True:
+ l = f.readline()
+ if l == '':
+ break
+ test_requirements.append(l.rstrip())
+f.close()
+
+
+setup(
+ package_data={
+ '': [
+ 'data/EIP165.json',
+ ],
+ },
+ include_package_data=True,
+ install_requires=requirements,
+ tests_require=test_requirements,
+ )
diff --git a/python/test_requirements.txt b/python/test_requirements.txt
@@ -0,0 +1,4 @@
+eth_tester==0.5.0b3
+py-evm==0.3.0a20
+rlp==2.0.1
+pytest==6.0.1
diff --git a/python/tests/test_eip165.py b/python/tests/test_eip165.py
@@ -0,0 +1,61 @@
+# standard imports
+import unittest
+import os
+import logging
+
+# local imports
+from chainlib.eth.unittest.ethtester import EthTesterCase
+from chainlib.eth.nonce import RPCNonceOracle
+from chainlib.eth.gas import OverrideGasOracle
+from chainlib.connection import RPCConnection
+from chainlib.eth.tx import (
+ TxFactory,
+ receipt,
+ )
+from chainlib.eth.eip165 import EIP165
+
+logging.basicConfig(level=logging.DEBUG)
+logg = logging.getLogger()
+
+script_dir = os.path.realpath(os.path.dirname(__file__))
+
+
+class TestSupports(EthTesterCase):
+
+ def setUp(self):
+ super(TestSupports, self).setUp()
+ self.conn = RPCConnection.connect(self.chain_spec, 'default')
+ nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn)
+
+ f = open(os.path.join(script_dir, 'testdata', 'Supports.bin'))
+ code = f.read()
+ f.close()
+
+ txf = TxFactory(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ tx = txf.template(self.accounts[0], None, use_nonce=True)
+ tx = txf.set_code(tx, code)
+ (tx_hash_hex, o) = txf.build(tx)
+
+ r = self.conn.do(o)
+ logg.debug('deployed with hash {}'.format(r))
+
+ o = receipt(tx_hash_hex)
+ r = self.conn.do(o)
+ self.address = r['contract_address']
+
+
+ def test_supports(self):
+ gas_oracle = OverrideGasOracle(limit=100000, conn=self.conn)
+ c = EIP165(self.chain_spec, gas_oracle=gas_oracle)
+ o = c.supports_interface(self.address, '0xdeadbeef', sender_address=self.accounts[0])
+ r = self.conn.do(o)
+ v = c.parse_supports_interface(r)
+ self.assertEqual(v, 1)
+
+ o = c.supports_interface(self.address, '0xbeeffeed', sender_address=self.accounts[0])
+ r = self.conn.do(o)
+ v = c.parse_supports_interface(r)
+ self.assertEqual(v, 0)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/python/tests/testdata/Supports.bin b/python/tests/testdata/Supports.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b506101c9806100206000396000f3fe608060405234801561001057600080fd5b5060043610610048576000357c01000000000000000000000000000000000000000000000000000000009004806301ffc9a71461004d575b600080fd5b610067600480360381019061006291906100f1565b61007d565b6040516100749190610129565b60405180910390f35b600063deadbeef7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156100d257600190506100d7565b600090505b919050565b6000813590506100eb8161017c565b92915050565b60006020828403121561010357600080fd5b6000610111848285016100dc565b91505092915050565b61012381610144565b82525050565b600060208201905061013e600083018461011a565b92915050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61018581610150565b811461019057600080fd5b5056fea264697066735822122073144ec34d71a86680325f1aee9a3b9041e22c422e7b1b82d409b303d52192de64736f6c63430008030033
+\ No newline at end of file
diff --git a/python/tests/testdata/Supports.sol b/python/tests/testdata/Supports.sol
@@ -0,0 +1,10 @@
+pragma solidity ^0.8.0;
+
+contract Supports {
+ function supportsInterface(bytes4 _sum) public pure returns (bool) {
+ if (_sum == 0xdeadbeef) {
+ return true;
+ }
+ return false;
+ }
+}