commit 8202f18c6d042b39a5014accb33eb1e693617851
Author: lash <dev@holbrook.no>
Date: Sat, 13 May 2023 16:00:01 +0100
Initial commit
Signed-off-by: lash <dev@holbrook.no>
Diffstat:
10 files changed, 204 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,3 @@
+__pycache__
+*.pyc
+build/
diff --git a/python/LICENSE b/python/LICENSE
@@ -0,0 +1,45 @@
+ Bprotocol Foundation (Bancor) LICENSE
+
+1. SUBJECT TO THE PROVISIONS SET FORTH HEREIN, INCLUDING “EFFECTIVE DATE”, YOU CAN
+ USE THIS CODE, FILE AND/OR SOFTWARE (“SOFTWARE”) ONLY IN CONNECTION WITH THE
+ BANCOR LIQUIDITY NETWORK AND/OR THE USE OF BNT ("PERMITTED USE"). ANY OTHER USE IS
+ PROHIBITED UNLESS THE USER SHALL RECEIVE AN EXPLICIT PRIOR WRITTEN APPROVAL FROM
+ BPROTOCOL FOUNDATION (BANCOR) TO DO SO (PLEASE CONTACT license@bancor.network IN
+ THIS REGARD), WHICH APPROVAL, IF GIVEN, MAY REQUIRE THE OBTAINMENT OF SEPARATE
+ LICENSE UNDER A DIFFERENT LICENSING MODEL. USING THIS SOFTWARE NOT IN THE FRAME OF
+ SUCH PERMITTED USE MAY, AMONG OTHERS, ALSO BREACH PATENT RIGHTS CONCERNING PATENTS
+ WHICH ARE EMBODIED/INCORPORATED/USED IN THIS SOFTWARE.
+
+2. ANY SUCH PERMITTED USE SHOULD ALSO COMPLY WITH THE TERMS BELOW.
+
+3. Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+A. Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+B. Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+C. Neither the name of the copyright holder nor the names of its contributors may be
+ used to endorse or promote products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+EFFECTIVE DATE: THIS LICENSE SHALL APPLY ONLY TO SOFTWARE (OR ANY VERSION THEREOF),
+THAT HAS BEEN PUBLISHED AFTER THE DATE AND TIME THIS LICENSE HAS BEEN FIRST PUBLISHED
+(“EFFECTIVE DATE”); Any previous versions published prior to the effective date (“Older Versions”)
+shall remain licensed under the Apache License, Version 2.0 (the "Older Versions License");
+You may obtain a copy of the Older Version License at http://www.apache.org/licenses/LICENSE-2.0
+you may not use this file except in compliance with the Older Version License. Unless
+required by applicable law or agreed to in writing, Older Versions distributed under the
+Older Version License are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+OF ANY KIND, either express or implied. See the Older Version License for the specific
+language governing permissions and limitations under the Older Version License.
diff --git a/python/eth_writer/__init__.py b/python/eth_writer/__init__.py
@@ -0,0 +1 @@
+from .interface import *
diff --git a/python/eth_writer/interface.py b/python/eth_writer/interface.py
@@ -0,0 +1,44 @@
+# external imports
+from chainlib.eth.tx import TxFormat
+from chainlib.eth.tx import TxFactory
+from chainlib.jsonrpc import JSONRPCRequest
+from chainlib.eth.constant import ZERO_ADDRESS
+from chainlib.eth.contract import ABIContractEncoder
+from chainlib.eth.contract import ABIContractType
+from hexathon import add_0x
+
+class EthWriter(TxFactory):
+
+ def __single_address_method(self, method, contract_address, sender_address, address, tx_format=TxFormat.JSONRPC):
+ enc = ABIContractEncoder()
+ enc.method(method)
+ enc.typ(ABIContractType.ADDRESS)
+ enc.address(address)
+ data = enc.get()
+ tx = self.template(sender_address, contract_address, use_nonce=True)
+ tx = self.set_code(tx, data)
+ tx = self.finalize(tx, tx_format)
+ return tx
+
+
+ def add_writer(self, contract_address, sender_address, address, tx_format=TxFormat.JSONRPC):
+ return self.__single_address_method('addWriter', contract_address, sender_address, address, tx_format)
+
+
+ def delete_writer(self, contract_address, sender_address, address, tx_format=TxFormat.JSONRPC):
+ return self.__single_address_method('deleteWriter', contract_address, sender_address, address, tx_format)
+
+
+ def is_writer(self, contract_address, address, sender_address=ZERO_ADDRESS, id_generator=None):
+ j = JSONRPCRequest(id_generator)
+ o = j.template()
+ o['method'] = 'eth_call'
+ enc = ABIContractEncoder()
+ enc.method('isWriter')
+ enc.typ(ABIContractType.ADDRESS)
+ enc.address(address)
+ 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
diff --git a/python/eth_writer/unittest/__init__.py b/python/eth_writer/unittest/__init__.py
@@ -0,0 +1 @@
+from .base import TestEthWriterInterface
diff --git a/python/eth_writer/unittest/base.py b/python/eth_writer/unittest/base.py
@@ -0,0 +1,45 @@
+# external imports
+from chainlib.eth.unittest.ethtester import EthTesterCase
+from chainlib.connection import RPCConnection
+from chainlib.eth.nonce import RPCNonceOracle
+from chainlib.eth.tx import receipt
+
+# local imports
+from eth_writer import EthWriter
+
+
+class TestEthWriterInterface:
+
+ def test_add_delete(self):
+ writer_contract_address = self.contracts['writer']
+ publisher_address = self.roles.get('publisher')
+ writer_account = self.roles['writer']
+
+ nonce_oracle = RPCNonceOracle(self.publisher, conn=self.conn)
+ c = EthWriter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+
+ o = c.is_writer(writer_contract_address, publisher_address, sender_address=publisher_address)
+ r = self.rpc.do(o)
+ self.assertEqual(int(r, 16), 1)
+
+ self.alice = self.accounts[1]
+ (tx_hash, o) = c.add_writer(writer_contract_address, publisher_address, writer_account)
+ self.rpc.do(o)
+ o = receipt(tx_hash)
+ r = self.rpc.do(o)
+ self.assertEqual(r['status'], 1)
+
+ o = c.is_writer(writer_contract_address, writer_account, sender_address=publisher_address)
+ r = self.rpc.do(o)
+ self.assertEqual(int(r, 16), 1)
+
+ self.alice = self.accounts[1]
+ (tx_hash, o) = c.delete_writer(writer_contract_address, publisher_address, writer_account)
+ self.rpc.do(o)
+ o = receipt(tx_hash)
+ r = self.rpc.do(o)
+ self.assertEqual(r['status'], 1)
+
+ o = c.is_writer(writer_contract_address, self.alice, sender_address=publisher_address)
+ r = self.rpc.do(o)
+ self.assertEqual(int(r, 16), 0)
diff --git a/python/requirements.txt b/python/requirements.txt
@@ -0,0 +1 @@
+chainlib-eth~=0.4.22
diff --git a/python/setup.cfg b/python/setup.cfg
@@ -0,0 +1,29 @@
+[metadata]
+name = eth-writer
+version = 0.0.1
+description = An interface for non-owner write access to smart contract instance.
+author = Louis Holbrook
+author_email = dev@holbrook.no
+url = https://holbrook.no/src/eth-writer/log.html
+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 :: Software Development :: Libraries
+ #Topic :: Blockchain :: EVM
+license = GPL3
+licence_files =
+ LICENSE.txt
+
+[options]
+include_package_data = True
+python_requires = >= 3.7
+packages =
+ eth_writer
+ eth_writer.unittest
diff --git a/python/setup.py b/python/setup.py
@@ -0,0 +1,32 @@
+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/*.abi.json',
+ 'data/*.bin',
+ ],
+ },
+ 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,3 @@
+eth_tester==0.5.0b3
+py-evm==0.3.0a20
+eth-interface==0.1.1