eth-owned

EIP-173 interface and tools for chainlib-eth
git clone git://holbrook.no/eth-owned.git
Log | Files | Refs

commit bd02667887efa4a471fe16dc940e8da11508edc7
parent c4ebf45cc23154d2eccba54e5674e061911d66ec
Author: nolash <dev@holbrook.no>
Date:   Fri, 30 Apr 2021 09:24:49 +0200

Improve generic owned code

Diffstat:
Mpython/eth_owned/data/VoidOwner.bin | 4++--
Mpython/eth_owned/data/VoidOwner.json | 2+-
Mpython/eth_owned/owned.py | 75+++++++++++++++++++++++++++++++++++++++------------------------------------
Mpython/eth_owned/void.py | 12------------
Dpython/tests/test_basic.py | 130-------------------------------------------------------------------------------
Apython/tests/test_owned.py | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apython/tests/test_void.py | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apython/tests/testdata/Owned.bin | 2++
Apython/tests/testdata/Owned.sol | 32++++++++++++++++++++++++++++++++
Msolidity/VoidOwner.sol | 3++-
10 files changed, 338 insertions(+), 182 deletions(-)

diff --git a/python/eth_owned/data/VoidOwner.bin b/python/eth_owned/data/VoidOwner.bin @@ -1 +1 @@ -608060405234801561001057600080fd5b50610676806100206000396000f3fe608060405234801561001057600080fd5b5060043610610048576000357c010000000000000000000000000000000000000000000000000000000090048063295a75371461004d575b600080fd5b610067600480360381019061006291906103a2565b61007d565b60405161007491906104bb565b60405180910390f35b600080606060008473ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f79ba5097000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161012b9190610489565b6000604051808303816000865af19150503d8060008114610168576040519150601f19603f3d011682016040523d82523d6000602084013e61016d565b606091505b508093508194505050826101b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ad906104d6565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f8da5cb5b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161025d9190610489565b6000604051808303816000865af19150503d806000811461029a576040519150601f19603f3d011682016040523d82523d6000602084013e61029f565b606091505b508093508194505050826102e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102df906104f6565b60405180910390fd5b818060200190518101906102fc91906103cb565b90508073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161461033657600080fd5b7fdc3c82f4776932041f15a08f769aadd6ed44c2a975e64bbf0fde8cf812f8b6b88560405161036591906104a0565b60405180910390a1829350505050919050565b60008135905061038781610612565b92915050565b60008151905061039c81610629565b92915050565b6000602082840312156103b457600080fd5b60006103c284828501610378565b91505092915050565b6000602082840312156103dd57600080fd5b60006103eb8482850161038d565b91505092915050565b6103fd8161053d565b82525050565b61040c81610561565b82525050565b600061041d82610516565b6104278185610521565b935061043781856020860161058d565b80840191505092915050565b6000610450600a8361052c565b915061045b826105c0565b602082019050919050565b6000610473600d8361052c565b915061047e826105e9565b602082019050919050565b60006104958284610412565b915081905092915050565b60006020820190506104b560008301846103f4565b92915050565b60006020820190506104d06000830184610403565b92915050565b600060208201905081810360008301526104ef81610443565b9050919050565b6000602082019050818103600083015261050f81610466565b9050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b60006105488261056d565b9050919050565b600061055a8261056d565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60005b838110156105ab578082015181840152602081019050610590565b838111156105ba576000848401525b50505050565b7f4552525f41434345505400000000000000000000000000000000000000000000600082015250565b7f4552525f494e5445524641434500000000000000000000000000000000000000600082015250565b61061b8161053d565b811461062657600080fd5b50565b6106328161054f565b811461063d57600080fd5b5056fea264697066735822122011c0a1dbbda64501370d85ab3d0ff50c4e0167db06d034c5230fb47d13e0de0a64736f6c63430008030033 -\ No newline at end of file +608060405234801561001057600080fd5b50610676806100206000396000f3fe608060405234801561001057600080fd5b5060043610610048576000357c0100000000000000000000000000000000000000000000000000000000900480636b5783391461004d575b600080fd5b610067600480360381019061006291906103a2565b61007d565b60405161007491906104bb565b60405180910390f35b600080606060008473ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f79ba5097000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161012b9190610489565b6000604051808303816000865af19150503d8060008114610168576040519150601f19603f3d011682016040523d82523d6000602084013e61016d565b606091505b508093508194505050826101b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ad906104d6565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f8da5cb5b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161025d9190610489565b6000604051808303816000865af19150503d806000811461029a576040519150601f19603f3d011682016040523d82523d6000602084013e61029f565b606091505b508093508194505050826102e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102df906104f6565b60405180910390fd5b818060200190518101906102fc91906103cb565b90508073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161461033657600080fd5b7fdc3c82f4776932041f15a08f769aadd6ed44c2a975e64bbf0fde8cf812f8b6b88560405161036591906104a0565b60405180910390a1829350505050919050565b60008135905061038781610612565b92915050565b60008151905061039c81610629565b92915050565b6000602082840312156103b457600080fd5b60006103c284828501610378565b91505092915050565b6000602082840312156103dd57600080fd5b60006103eb8482850161038d565b91505092915050565b6103fd8161053d565b82525050565b61040c81610561565b82525050565b600061041d82610516565b6104278185610521565b935061043781856020860161058d565b80840191505092915050565b6000610450600a8361052c565b915061045b826105c0565b602082019050919050565b6000610473600d8361052c565b915061047e826105e9565b602082019050919050565b60006104958284610412565b915081905092915050565b60006020820190506104b560008301846103f4565b92915050565b60006020820190506104d06000830184610403565b92915050565b600060208201905081810360008301526104ef81610443565b9050919050565b6000602082019050818103600083015261050f81610466565b9050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b60006105488261056d565b9050919050565b600061055a8261056d565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60005b838110156105ab578082015181840152602081019050610590565b838111156105ba576000848401525b50505050565b7f4552525f41434345505400000000000000000000000000000000000000000000600082015250565b7f4552525f494e5445524641434500000000000000000000000000000000000000600082015250565b61061b8161053d565b811461062657600080fd5b50565b6106328161054f565b811461063d57600080fd5b5056fea26469706673582212209f8948524a5beced42c684c362cc928629510879f6e490ecd2cbec1ad52449e564736f6c63430008030033 +\ No newline at end of file diff --git a/python/eth_owned/data/VoidOwner.json b/python/eth_owned/data/VoidOwner.json @@ -1 +1 @@ -[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_result","type":"address"}],"name":"OwnershipTaken","type":"event"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"omNom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] +[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_result","type":"address"}],"name":"OwnershipTaken","type":"event"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"takeOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/python/eth_owned/owned.py b/python/eth_owned/owned.py @@ -1,34 +1,35 @@ -# standard imports -import logging -import json -import os - # external imports -from chainlib.eth.tx import ( - TxFactory, - TxFormat, - ) +from hexathon import ( + add_0x, + ) + +# local imports from chainlib.eth.contract import ( ABIContractEncoder, ABIContractDecoder, ABIContractType, abi_decode_single, + ) +from chainlib.jsonrpc import jsonrpc_template +from chainlib.eth.tx import ( + TxFactory, + TxFormat, ) from chainlib.eth.constant import ZERO_ADDRESS -from chainlib.jsonrpc import ( - jsonrpc_template, - ) -from hexathon import add_0x -logg = logging.getLogger() +class EIP173(TxFactory): -moddir = os.path.dirname(__file__) -datadir = os.path.join(moddir, 'data') - - -class Owned(TxFactory): + def transfer_ownership(self, contract_address, sender_address, new_owner_address, tx_format=TxFormat.JSONRPC): + enc = ABIContractEncoder() + enc.method('transferOwnership') + enc.typ(ABIContractType.ADDRESS) + enc.address(new_owner_address) + data = add_0x(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 - interfaces = None def owner(self, contract_address, sender_address=ZERO_ADDRESS): o = jsonrpc_template() @@ -39,32 +40,34 @@ class Owned(TxFactory): tx = self.template(sender_address, contract_address) tx = self.set_code(tx, data) o['params'].append(self.normalize(tx)) + o['params'].append('latest') return o - def transfer_ownership(self, sender_address, contract_address, address, tx_format=TxFormat.JSONRPC): + @classmethod + def parse_owner(self, v): + return abi_decode_single(ABIContractType.ADDRESS, v) + + +class Owned(EIP173): + + def accept_ownership(self, contract_address, sender_address, tx_format=TxFormat.JSONRPC): enc = ABIContractEncoder() - enc.method('transferOwnership') - enc.typ(ABIContractType.ADDRESS) - enc.address(address) - data = enc.get() + enc.method('acceptOwnership') + data = add_0x(enc.get()) tx = self.template(sender_address, contract_address, use_nonce=True) tx = self.set_code(tx, data) - tx = self.finalize(tx, tx_format) + tx = self.finalize(tx, tx_format) return tx - def accept_ownership(self, sender_address, contract_address, tx_format=TxFormat.JSONRPC): + def take_ownership(self, contract_address, sender_address, resource_address, tx_format=TxFormat.JSONRPC): enc = ABIContractEncoder() - enc.method('acceptOwnership') - data = enc.get() + enc.method('takeOwnership') + enc.typ(ABIContractType.ADDRESS) + enc.address(resource_address) + data = add_0x(enc.get()) tx = self.template(sender_address, contract_address, use_nonce=True) tx = self.set_code(tx, data) - tx = self.finalize(tx, tx_format) + tx = self.finalize(tx, tx_format) return tx - - - @classmethod - def parse_owner(self, v): - return abi_decode_single(ABIContractType.ADDRESS, v) - diff --git a/python/eth_owned/void.py b/python/eth_owned/void.py @@ -63,15 +63,3 @@ class VoidOwner(TxFactory): tx = self.template(sender_address, None, use_nonce=True) tx = self.set_code(tx, code) return self.build(tx) - - - def take_ownership(self, sender_address, contract_address, address, tx_format=TxFormat.JSONRPC): - enc = ABIContractEncoder() - enc.method('omNom') - 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 diff --git a/python/tests/test_basic.py b/python/tests/test_basic.py @@ -1,130 +0,0 @@ -# standard imports -import os -import unittest -import json -import logging - -# external imports -from chainlib.eth.unittest.ethtester import EthTesterCase -from chainlib.connection import RPCConnection -from chainlib.eth.address import to_checksum_address -from chainlib.eth.nonce import RPCNonceOracle -from chainlib.eth.tx import ( - receipt, - transaction, - TxFormat, - TxFactory, - ) -from chainlib.eth.contract import ( - abi_decode_single, - ABIContractType, - ) -from chainlib.jsonrpc import jsonrpc_template -from chainlib.eth.contract import ( - ABIContractEncoder, - ) -from hexathon import add_0x - -# local imports -from eth_owned.void import VoidOwner -from eth_owned import ( - Owned, - data_dir, - ) - -logging.basicConfig(level=logging.DEBUG) -logg = logging.getLogger() - -testdir = os.path.dirname(__file__) - - -class Test(EthTesterCase): - - - def setUp(self): - super(Test, self).setUp() - self.conn = RPCConnection.connect(self.chain_spec, 'default') - nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) - self.o = VoidOwner(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash_hex, o) = self.o.constructor(self.accounts[0]) - 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'] - - f = open(os.path.join(data_dir, 'Owned.bin'), 'r') - b = 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, b) - (tx_hash_hex, o) = txf.build(tx) - r = self.conn.do(o) - - o = receipt(tx_hash_hex) - r = self.conn.do(o) - self.owned_demo_address = r['contract_address'] - - - def test_accept(self): - nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) - txf = TxFactory(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - - c = Owned(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash_hex, o) = c.transfer_ownership(self.accounts[0], self.owned_demo_address, self.accounts[1]) - r = self.conn.do(o) - - o = receipt(tx_hash_hex) - r = self.conn.do(o) - self.assertEqual(r['status'], 1) - - nonce_oracle = RPCNonceOracle(self.accounts[1], self.conn) - c = Owned(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash_hex, o) = c.accept_ownership(self.accounts[1], self.owned_demo_address) - - r = self.conn.do(o) - - o = receipt(tx_hash_hex) - r = self.conn.do(o) - self.assertEqual(r['status'], 1) - - o = c.owner(self.owned_demo_address, sender_address=self.accounts[0]) - r = self.conn.do(o) - owner_address = abi_decode_single(ABIContractType.ADDRESS, r) - self.assertEqual(owner_address, self.accounts[1]) - - - def test_void(self): - nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) - txf = TxFactory(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - - c = Owned(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash_hex, o) = c.transfer_ownership(self.accounts[0], self.owned_demo_address, self.address) - r = self.conn.do(o) - - o = receipt(tx_hash_hex) - r = self.conn.do(o) - self.assertEqual(r['status'], 1) - - c = VoidOwner(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash_hex, o) = c.take_ownership(self.accounts[0], self.address, self.owned_demo_address) - - r = self.conn.do(o) - - o = receipt(tx_hash_hex) - r = self.conn.do(o) - self.assertEqual(r['status'], 1) - - c = Owned(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - o = c.owner(self.owned_demo_address, sender_address=self.accounts[0]) - - r = self.conn.do(o) - owner_address = abi_decode_single(ABIContractType.ADDRESS, r) - self.assertEqual(owner_address, self.address) - - -if __name__ == '__main__': - unittest.main() diff --git a/python/tests/test_owned.py b/python/tests/test_owned.py @@ -0,0 +1,133 @@ +# standard imports +import unittest +import os +import logging + +# external 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, + ) + +# local imports +from eth_owned.owned import ( + EIP173, + Owned, + ) + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + +script_dir = os.path.realpath(os.path.dirname(__file__)) + + +class TestOwned(EthTesterCase): + + def setUp(self): + super(TestOwned, 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', 'Owned.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_owned(self): + c = EIP173(self.chain_spec) + o = c.owner(self.address, sender_address=self.accounts[0]) + r = self.conn.do(o) + owner = c.parse_owner(r) + self.assertEqual(owner, self.accounts[0]) + + + def test_transfer_ownership(self): + nonce_oracle = RPCNonceOracle(self.accounts[2], self.conn) + gas_oracle = OverrideGasOracle(limit=8000000, conn=self.conn) + c = EIP173(self.chain_spec, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle, signer=self.signer) + (tx_hash_hex, o) = c.transfer_ownership(self.address, self.accounts[2], self.accounts[1]) + r = self.conn.do(o) + + o = receipt(tx_hash_hex) + r = self.conn.do(o) + self.assertEqual(r['status'], 0) + + nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) + c = EIP173(self.chain_spec, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle, signer=self.signer) + (tx_hash_hex, o) = c.transfer_ownership(self.address, self.accounts[0], self.accounts[1]) + r = self.conn.do(o) + + o = receipt(tx_hash_hex) + r = self.conn.do(o) + self.assertEqual(r['status'], 1) + + + def test_accept_ownership(self): + nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) + gas_oracle = OverrideGasOracle(limit=8000000, conn=self.conn) + c = Owned(self.chain_spec, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle, signer=self.signer) + (tx_hash_hex, o) = c.transfer_ownership(self.address, self.accounts[0], self.accounts[1]) + r = self.conn.do(o) + + nonce_oracle = RPCNonceOracle(self.accounts[2], self.conn) + c = Owned(self.chain_spec, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle, signer=self.signer) + (tx_hash_hex, o) = c.accept_ownership(self.address, self.accounts[2]) + r = self.conn.do(o) + + o = receipt(tx_hash_hex) + r = self.conn.do(o) + self.assertEqual(r['status'], 0) + + nonce_oracle = RPCNonceOracle(self.accounts[1], self.conn) + c = Owned(self.chain_spec, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle, signer=self.signer) + (tx_hash_hex, o) = c.accept_ownership(self.address, self.accounts[1]) + r = self.conn.do(o) + + o = receipt(tx_hash_hex) + r = self.conn.do(o) + self.assertEqual(r['status'], 1) + + o = c.owner(self.address, sender_address=self.accounts[0]) + r = self.conn.do(o) + owner = c.parse_owner(r) + self.assertEqual(owner, self.accounts[1]) + + + def test_take_ownership(self): + nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) + gas_oracle = OverrideGasOracle(limit=8000000, conn=self.conn) + c = Owned(self.chain_spec, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle, signer=self.signer) + (tx_hash_hex, o) = c.transfer_ownership(self.address, self.accounts[0], self.address) + r = self.conn.do(o) + + (tx_hash_hex, o) = c.take_ownership(self.address, self.accounts[0], self.address) + r = self.conn.do(o) + + o = receipt(tx_hash_hex) + r = self.conn.do(o) + self.assertEqual(r['status'], 1) + + o = c.owner(self.address, sender_address=self.accounts[0]) + r = self.conn.do(o) + owner = c.parse_owner(r) + self.assertEqual(owner, self.address) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/tests/test_void.py b/python/tests/test_void.py @@ -0,0 +1,127 @@ +# standard imports +import os +import unittest +import json +import logging + +# external imports +from chainlib.eth.unittest.ethtester import EthTesterCase +from chainlib.connection import RPCConnection +from chainlib.eth.address import to_checksum_address +from chainlib.eth.nonce import RPCNonceOracle +from chainlib.eth.tx import ( + receipt, + transaction, + TxFormat, + TxFactory, + ) +from chainlib.eth.contract import ( + abi_decode_single, + ABIContractType, + ) +from chainlib.jsonrpc import jsonrpc_template +from chainlib.eth.contract import ( + ABIContractEncoder, + ) +from hexathon import add_0x + +# local imports +from eth_owned.void import VoidOwner +from eth_owned import ( + Owned, + data_dir, + ) + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + +testdir = os.path.dirname(__file__) + + +class Test(EthTesterCase): + + + def setUp(self): + super(Test, self).setUp() + self.conn = RPCConnection.connect(self.chain_spec, 'default') + nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) + self.o = VoidOwner(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = self.o.constructor(self.accounts[0]) + 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'] + + f = open(os.path.join(data_dir, 'Owned.bin'), 'r') + b = 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, b) + (tx_hash_hex, o) = txf.build(tx) + r = self.conn.do(o) + + o = receipt(tx_hash_hex) + r = self.conn.do(o) + self.owned_demo_address = r['contract_address'] + + + def test_accept(self): + nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) + txf = TxFactory(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + + c = Owned(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.transfer_ownership(self.owned_demo_address, self.accounts[0], self.accounts[1]) + r = self.conn.do(o) + + o = receipt(tx_hash_hex) + r = self.conn.do(o) + self.assertEqual(r['status'], 1) + + nonce_oracle = RPCNonceOracle(self.accounts[1], self.conn) + c = Owned(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.accept_ownership(self.owned_demo_address, self.accounts[1]) + + r = self.conn.do(o) + + o = receipt(tx_hash_hex) + r = self.conn.do(o) + self.assertEqual(r['status'], 1) + + o = c.owner(self.owned_demo_address, sender_address=self.accounts[0]) + r = self.conn.do(o) + owner_address = abi_decode_single(ABIContractType.ADDRESS, r) + self.assertEqual(owner_address, self.accounts[1]) + + + def test_void(self): + nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) + txf = TxFactory(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + + c = Owned(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.transfer_ownership(self.owned_demo_address, self.accounts[0], self.address) + r = self.conn.do(o) + + o = receipt(tx_hash_hex) + r = self.conn.do(o) + self.assertEqual(r['status'], 1) + + (tx_hash_hex, o) = c.take_ownership(self.address, self.accounts[0], self.owned_demo_address) + r = self.conn.do(o) + + o = receipt(tx_hash_hex) + r = self.conn.do(o) + self.assertEqual(r['status'], 1) + + o = c.owner(self.owned_demo_address, sender_address=self.accounts[0]) + r = self.conn.do(o) + + owner_address = abi_decode_single(ABIContractType.ADDRESS, r) + self.assertEqual(owner_address, self.address) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/tests/testdata/Owned.bin b/python/tests/testdata/Owned.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610624806100606000396000f3fe608060405234801561001057600080fd5b5060043610610069576000357c0100000000000000000000000000000000000000000000000000000000900480636b5783391461006e57806379ba50971461009e5780638da5cb5b146100bc578063f2fde38b146100da575b600080fd5b6100886004803603810190610083919061040e565b61010a565b60405161009591906104db565b60405180910390f35b6100a661024c565b6040516100b391906104db565b60405180910390f35b6100c4610331565b6040516100d191906104c0565b60405180910390f35b6100f460048036038101906100ef919061040e565b610355565b60405161010191906104db565b60405180910390f35b60008060608373ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f79ba5097000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516101b691906104a9565b6000604051808303816000865af19150503d80600081146101f3576040519150601f19603f3d011682016040523d82523d6000602084013e6101f8565b606091505b50809250819350505081610241576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610238906104f6565b60405180910390fd5b600192505050919050565b60003373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146102a857600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146103af57600080fd5b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b600081359050610408816105d7565b92915050565b60006020828403121561042057600080fd5b600061042e848285016103f9565b91505092915050565b6104408161053d565b82525050565b61044f8161054f565b82525050565b600061046082610516565b61046a8185610521565b935061047a81856020860161057b565b80840191505092915050565b6000610493600a8361052c565b915061049e826105ae565b602082019050919050565b60006104b58284610455565b915081905092915050565b60006020820190506104d56000830184610437565b92915050565b60006020820190506104f06000830184610446565b92915050565b6000602082019050818103600083015261050f81610486565b9050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b60006105488261055b565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60005b8381101561059957808201518184015260208101905061057e565b838111156105a8576000848401525b50505050565b7f4552525f41434345505400000000000000000000000000000000000000000000600082015250565b6105e08161053d565b81146105eb57600080fd5b5056fea26469706673582212205909b3637c67bdd4ec307d714ab75291de5f5d7ae0872a6fd6889aad21de847464736f6c63430008030033 +\ No newline at end of file diff --git a/python/tests/testdata/Owned.sol b/python/tests/testdata/Owned.sol @@ -0,0 +1,32 @@ +pragma solidity ^0.8.0; + +contract Owned { + address public owner; + address newOwner; + + constructor() public { + owner = msg.sender; + } + + function transferOwnership(address _newOwner) public returns (bool) { + require(owner == msg.sender); + newOwner = _newOwner; + return true; + } + + function acceptOwnership() public returns (bool) { + require(newOwner == msg.sender); + owner = msg.sender; + newOwner = address(0); + return true; + } + + function takeOwnership(address _ownable) public returns (bool) { + bool ok; + bytes memory result; + + (ok, result) = _ownable.call(abi.encodeWithSignature("acceptOwnership()")); + require(ok, "ERR_ACCEPT"); + return true; + } +} diff --git a/solidity/VoidOwner.sol b/solidity/VoidOwner.sol @@ -6,7 +6,8 @@ contract VoidOwner { event OwnershipTaken(address _result); - function omNom(address _contract) public returns (bool) { +// function omNom(address _contract) public returns (bool) { + function takeOwnership(address _contract) public returns (bool) { bool ok; bytes memory result; address newOwner;