diff --git a/python/eth_capped/unittest/base.py b/python/eth_capped/unittest/base.py index 23c60de..2c26b79 100644 --- a/python/eth_capped/unittest/base.py +++ b/python/eth_capped/unittest/base.py @@ -12,9 +12,6 @@ from chainlib.eth.tx import TxFormat from chainlib.eth.contract import ABIContractEncoder from chainlib.eth.contract import ABIContractType -# local imports -from eth_capped import EthCapped - script_dir = os.path.dirname(os.path.realpath(__file__)) contract_dir = os.path.join(script_dir, '..', '..', 'solidity') diff --git a/python/eth_seal/__init__.py b/python/eth_seal/__init__.py new file mode 100644 index 0000000..895733e --- /dev/null +++ b/python/eth_seal/__init__.py @@ -0,0 +1 @@ +from .seal import EthSeal diff --git a/python/eth_seal/seal.py b/python/eth_seal/seal.py new file mode 100644 index 0000000..da1293d --- /dev/null +++ b/python/eth_seal/seal.py @@ -0,0 +1,32 @@ +# 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 chainlib.eth.contract import abi_decode_single +from hexathon import add_0x + + +class EthSeal(TxFactory): + + def __noarg(self, method, contract_address, sender_address=ZERO_ADDRESS, id_generator=None): + j = JSONRPCRequest(id_generator) + o = j.template() + o['method'] = 'eth_call' + enc = ABIContractEncoder() + enc.method(method) + 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 + + + def max_seal_state(self, contract_address, sender_address=ZERO_ADDRESS, id_generator=None): + return self.__noarg('maxSealState', contract_address, sender_address=sender_address, id_generator=id_generator) + + + def seal_state(self, contract_address, sender_address=ZERO_ADDRESS, id_generator=None): + return self.__noarg('sealState', contract_address, sender_address=sender_address, id_generator=id_generator) diff --git a/python/eth_seal/unittest/__init__.py b/python/eth_seal/unittest/__init__.py new file mode 100644 index 0000000..00b5bcd --- /dev/null +++ b/python/eth_seal/unittest/__init__.py @@ -0,0 +1 @@ +from .interface import TestEthSealInterface diff --git a/python/eth_seal/unittest/base.py b/python/eth_seal/unittest/base.py new file mode 100644 index 0000000..0fbe55b --- /dev/null +++ b/python/eth_seal/unittest/base.py @@ -0,0 +1,60 @@ +# 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 + +script_dir = os.path.dirname(os.path.realpath(__file__)) +contract_dir = os.path.join(script_dir, '..', '..', 'solidity') + +logg = logging.getLogger(__name__) + + +class TestEthSeal(EthTesterCase): + + def setUp(self): + super(TestEthSeal, 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, 'SealTest.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) + + self.max_seal_state = 7 + 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'] + logg.debug('published seal test contract with hash {}'.format(r)) + + + def seal(self, contract_address, sender_address, v, tx_format=TxFormat.JSONRPC): + nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) + txf = TxFactory(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + enc = ABIContractEncoder() + enc.method('seal') + enc.typ(ABIContractType.UINT256) + enc.uint256(v) + data = enc.get() + tx = txf.template(sender_address, contract_address, use_nonce=True) + tx = txf.set_code(tx, data) + tx = txf.finalize(tx, tx_format) + return tx diff --git a/python/eth_seal/unittest/interface.py b/python/eth_seal/unittest/interface.py new file mode 100644 index 0000000..29809ea --- /dev/null +++ b/python/eth_seal/unittest/interface.py @@ -0,0 +1,21 @@ +# external imports +from chainlib.eth.tx import receipt + +# local imports +from eth_seal import EthSeal + + +class TestEthSealInterface: + + def __init__(self): + self.set_method = None + self.max_seal_state = 0 + + + def test_supply(self): + if self.max_seal_state == 0: + return + c = EthSeal(self.chain_spec) + o = c.max_seal_state(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + self.assertEqual(self.max_seal_state, int(r, 16)) diff --git a/python/solidity/SealTest.bin b/python/solidity/SealTest.bin new file mode 100644 index 0000000..45be26d --- /dev/null +++ b/python/solidity/SealTest.bin @@ -0,0 +1 @@ +6080604052600760015534801561001557600080fd5b50610355806100256000396000f3fe608060405234801561001057600080fd5b5060043610610069576000357c01000000000000000000000000000000000000000000000000000000009004806301ffc9a71461006e57806318cbbcfc1461009e57806331a5995d146100bc57806386fe212d146100da575b600080fd5b6100886004803603810190610083919061022f565b6100f6565b6040516100959190610277565b60405180910390f35b6100a66101a6565b6040516100b391906102ab565b60405180910390f35b6100c46101ac565b6040516100d191906102ab565b60405180910390f35b6100f460048036038101906100ef91906102f2565b6101b2565b005b60006301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361014a57600190506101a1565b630d7491f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361019c57600190506101a1565b600090505b919050565b60015481565b60005481565b60015481106101c057600080fd5b80600080828254179250508190555050565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61020c816101d7565b811461021757600080fd5b50565b60008135905061022981610203565b92915050565b600060208284031215610245576102446101d2565b5b60006102538482850161021a565b91505092915050565b60008115159050919050565b6102718161025c565b82525050565b600060208201905061028c6000830184610268565b92915050565b6000819050919050565b6102a581610292565b82525050565b60006020820190506102c0600083018461029c565b92915050565b6102cf81610292565b81146102da57600080fd5b50565b6000813590506102ec816102c6565b92915050565b600060208284031215610308576103076101d2565b5b6000610316848285016102dd565b9150509291505056fea26469706673582212208356fec8f4fc7719bf58ea1be5e22cf56cadb8367918f5b4e0a90cad23396bb064736f6c63430008130033 \ No newline at end of file diff --git a/python/solidity/SealTest.sol b/python/solidity/SealTest.sol new file mode 100644 index 0000000..2ac573f --- /dev/null +++ b/python/solidity/SealTest.sol @@ -0,0 +1,25 @@ +pragma solidity >=0.6.12; + +// Author: Louis Holbrook 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 +// SPDX-License-Identifier: AGPL-3.0-or-later + +contract SealTest { + event SealStateChange(bool indexed _final, uint256 _sealState); + uint256 public sealState; + uint256 public maxSealState = 7; + + function seal(uint256 _bits) public { + require(_bits < maxSealState); + sealState |= _bits; + } + + function supportsInterface(bytes4 _sum) public pure returns (bool) { + if (_sum == 0x01ffc9a7) { // EIP165 + return true; + } + if (_sum == 0x0d7491f8) { // Capped + return true; + } + return false; + } +} diff --git a/python/solidity/WriterTest.bin b/python/solidity/WriterTest.bin index 42e63a5..d7ce08f 100644 --- a/python/solidity/WriterTest.bin +++ b/python/solidity/WriterTest.bin @@ -1 +1 @@ -608060405234801561001057600080fd5b506104da806100206000396000f3fe608060405234801561001057600080fd5b5060043610610069576000357c01000000000000000000000000000000000000000000000000000000009004806301ffc9a71461006e5780632b29ba231461009e5780635ae06f7e146100ce578063da2824a8146100fe575b600080fd5b6100886004803603810190610083919061038c565b61012e565b60405161009591906103d4565b60405180910390f35b6100b860048036038101906100b3919061044d565b6101de565b6040516100c591906103d4565b60405180910390f35b6100e860048036038101906100e3919061044d565b6101fe565b6040516100f591906103d4565b60405180910390f35b6101186004803603810190610113919061044d565b610296565b60405161012591906103d4565b60405180910390f35b60006301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361018257600190506101d9565b63abe1f1f57c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036101d457600190506101d9565b600090505b919050565b60006020528060005260406000206000915054906101000a900460ff1681565b6000806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f9002f14780245e47491e7a2caae4712e7cea2e298e4e76c6916845145b90a51c826040516102859190610489565b60405180910390a160019050919050565b600060016000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f6ff3aa2ea7b53070f6d9d07a445d338d89e8edef44250ffa8be19f53910d4a2e8260405161031e9190610489565b60405180910390a160019050919050565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61036981610334565b811461037457600080fd5b50565b60008135905061038681610360565b92915050565b6000602082840312156103a2576103a161032f565b5b60006103b084828501610377565b91505092915050565b60008115159050919050565b6103ce816103b9565b82525050565b60006020820190506103e960008301846103c5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061041a826103ef565b9050919050565b61042a8161040f565b811461043557600080fd5b50565b60008135905061044781610421565b92915050565b6000602082840312156104635761046261032f565b5b600061047184828501610438565b91505092915050565b6104838161040f565b82525050565b600060208201905061049e600083018461047a565b9291505056fea2646970667358221220eb9501b6e730316c6065cb22becf0eed4e3b4bd3f1baa95ff6d20d56fcf85f2d64736f6c63430008130033 \ No newline at end of file +608060405234801561001057600080fd5b506104da806100206000396000f3fe608060405234801561001057600080fd5b5060043610610069576000357c01000000000000000000000000000000000000000000000000000000009004806301ffc9a71461006e5780632b29ba231461009e5780635ae06f7e146100ce578063da2824a8146100fe575b600080fd5b6100886004803603810190610083919061038c565b61012e565b60405161009591906103d4565b60405180910390f35b6100b860048036038101906100b3919061044d565b6101de565b6040516100c591906103d4565b60405180910390f35b6100e860048036038101906100e3919061044d565b6101fe565b6040516100f591906103d4565b60405180910390f35b6101186004803603810190610113919061044d565b610296565b60405161012591906103d4565b60405180910390f35b60006301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361018257600190506101d9565b63abe1f1f57c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036101d457600190506101d9565b600090505b919050565b60006020528060005260406000206000915054906101000a900460ff1681565b6000806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f9002f14780245e47491e7a2caae4712e7cea2e298e4e76c6916845145b90a51c826040516102859190610489565b60405180910390a160019050919050565b600060016000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f6ff3aa2ea7b53070f6d9d07a445d338d89e8edef44250ffa8be19f53910d4a2e8260405161031e9190610489565b60405180910390a160019050919050565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61036981610334565b811461037457600080fd5b50565b60008135905061038681610360565b92915050565b6000602082840312156103a2576103a161032f565b5b60006103b084828501610377565b91505092915050565b60008115159050919050565b6103ce816103b9565b82525050565b60006020820190506103e960008301846103c5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061041a826103ef565b9050919050565b61042a8161040f565b811461043557600080fd5b50565b60008135905061044781610421565b92915050565b6000602082840312156104635761046261032f565b5b600061047184828501610438565b91505092915050565b6104838161040f565b82525050565b600060208201905061049e600083018461047a565b9291505056fea26469706673582212206bef2d3402160122da272241da7b2729136d4bc1e4399f01ddd8c8a7d3b93cdd64736f6c63430008130033 \ No newline at end of file diff --git a/python/tests/test_seal.py b/python/tests/test_seal.py new file mode 100644 index 0000000..c92b5db --- /dev/null +++ b/python/tests/test_seal.py @@ -0,0 +1,30 @@ +# 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_seal import EthSeal +from eth_seal.unittest import TestEthSealInterface +from eth_seal.unittest.base import TestEthSeal + + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + + +class TestSealBase(TestEthSeal, TestEthSealInterface, TestERC165): + + def setUp(self): + super(TestSealBase, self).setUp() + self.add_interface_check('0d7491f8') + self.set_method = self.seal + + +if __name__ == '__main__': + unittest.main()