diff --git a/python/eth_writer/unittest/__init__.py b/python/eth_writer/unittest/__init__.py index 23027db..fe4c35d 100644 --- a/python/eth_writer/unittest/__init__.py +++ b/python/eth_writer/unittest/__init__.py @@ -1 +1 @@ -from .base import TestEthWriterInterface +from .interface import TestEthWriterInterface diff --git a/python/eth_writer/unittest/base.py b/python/eth_writer/unittest/base.py index 1015211..921b5a2 100644 --- a/python/eth_writer/unittest/base.py +++ b/python/eth_writer/unittest/base.py @@ -1,45 +1,58 @@ +# standard imports +import os +import logging + # 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 +from chainlib.eth.tx import TxFactory +from chainlib.eth.tx import TxFormat +from chainlib.eth.contract import ABIContractEncoder +from chainlib.eth.contract import ABIContractType # local imports from eth_writer import EthWriter +script_dir = os.path.dirname(os.path.realpath(__file__)) +contract_dir = os.path.join(script_dir, '..', '..', 'solidity') -class TestEthWriterInterface: +logg = logging.getLogger(__name__) - 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) +class TestEthWriter(EthTesterCase): + + def setUp(self): + super(TestEthWriter, self).setUp() + + self.set_method = None + + self.conn = RPCConnection.connect(self.chain_spec, 'default') + nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) + + f = open(os.path.join(contract_dir, 'WriterTest.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) + self.conn.do(o) + o = receipt(tx_hash_hex) + r = self.conn.do(o) + self.assertEqual(r['status'], 1) + self.address = r['contract_address'] + self.contracts['writer'] = self.address + self.roles['publisher'] = self.accounts[0] + self.roles['writer'] = self.accounts[1] + logg.debug('published writer test contract with hash {}'.format(r)) + 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) + (tx_hash, o) = c.add_writer(self.address, self.accounts[0], self.accounts[0]) 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/eth_writer/unittest/interface.py b/python/eth_writer/unittest/interface.py new file mode 100644 index 0000000..1015211 --- /dev/null +++ b/python/eth_writer/unittest/interface.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/solidity/WriterTest.bin b/python/solidity/WriterTest.bin new file mode 100644 index 0000000..42e63a5 --- /dev/null +++ b/python/solidity/WriterTest.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b506104da806100206000396000f3fe608060405234801561001057600080fd5b5060043610610069576000357c01000000000000000000000000000000000000000000000000000000009004806301ffc9a71461006e5780632b29ba231461009e5780635ae06f7e146100ce578063da2824a8146100fe575b600080fd5b6100886004803603810190610083919061038c565b61012e565b60405161009591906103d4565b60405180910390f35b6100b860048036038101906100b3919061044d565b6101de565b6040516100c591906103d4565b60405180910390f35b6100e860048036038101906100e3919061044d565b6101fe565b6040516100f591906103d4565b60405180910390f35b6101186004803603810190610113919061044d565b610296565b60405161012591906103d4565b60405180910390f35b60006301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361018257600190506101d9565b63abe1f1f57c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036101d457600190506101d9565b600090505b919050565b60006020528060005260406000206000915054906101000a900460ff1681565b6000806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f9002f14780245e47491e7a2caae4712e7cea2e298e4e76c6916845145b90a51c826040516102859190610489565b60405180910390a160019050919050565b600060016000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f6ff3aa2ea7b53070f6d9d07a445d338d89e8edef44250ffa8be19f53910d4a2e8260405161031e9190610489565b60405180910390a160019050919050565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61036981610334565b811461037457600080fd5b50565b60008135905061038681610360565b92915050565b6000602082840312156103a2576103a161032f565b5b60006103b084828501610377565b91505092915050565b60008115159050919050565b6103ce816103b9565b82525050565b60006020820190506103e960008301846103c5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061041a826103ef565b9050919050565b61042a8161040f565b811461043557600080fd5b50565b60008135905061044781610421565b92915050565b6000602082840312156104635761046261032f565b5b600061047184828501610438565b91505092915050565b6104838161040f565b82525050565b600060208201905061049e600083018461047a565b9291505056fea2646970667358221220eb9501b6e730316c6065cb22becf0eed4e3b4bd3f1baa95ff6d20d56fcf85f2d64736f6c63430008130033 \ No newline at end of file diff --git a/python/solidity/WriterTest.sol b/python/solidity/WriterTest.sol new file mode 100644 index 0000000..346258e --- /dev/null +++ b/python/solidity/WriterTest.sol @@ -0,0 +1,33 @@ +pragma solidity >=0.6.3; + +// Author: Louis Holbrook 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 +// SPDX-License-Identifier: AGPL-3.0-or-later + +contract MinterTest { + mapping (address => bool ) public isWriter; + + event WriterAdded(address _writer); + event WriterDeleted(address _writer); + + function addWriter(address _writer) public returns (bool) { + isWriter[_writer] = true; + emit WriterAdded(_writer); + return true; + } + + function deleteWriter(address _writer) public returns (bool) { + isWriter[_writer] = false; + emit WriterDeleted(_writer); + return true; + } + + function supportsInterface(bytes4 _sum) public pure returns (bool) { + if (_sum == 0x01ffc9a7) { // EIP165 + return true; + } + if (_sum == 0xabe1f1f5) { // Writer + return true; + } + return false; + } +} diff --git a/python/tests/test_writer.py b/python/tests/test_writer.py new file mode 100644 index 0000000..648e8d8 --- /dev/null +++ b/python/tests/test_writer.py @@ -0,0 +1,29 @@ +# standard imports +import unittest +import logging +import os +from chainlib.eth.nonce import RPCNonceOracle +from chainlib.eth.tx import receipt +from eth_erc20 import ERC20 +from giftable_erc20_token import GiftableToken +from eth_interface.unittest import TestERC165 + +# local imports +from eth_writer import EthWriter +from eth_writer.unittest import TestEthWriterInterface +from eth_writer.unittest.base import TestEthWriter + + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + + +class TestWriterBase(TestEthWriter, TestEthWriterInterface, TestERC165): + + def setUp(self): + super(TestWriterBase, self).setUp() + self.add_interface_check('abe1f1f5') + + +if __name__ == '__main__': + unittest.main()