commit c23a89a770a0f2324b685f5d0db45449ea61c9e5
Author: nolash <dev@holbrook.no>
Date: Wed, 3 Feb 2021 11:26:36 +0100
Initial commit
Diffstat:
4 files changed, 174 insertions(+), 0 deletions(-)
diff --git a/python/tests/test_basic.py b/python/tests/test_basic.py
@@ -0,0 +1,101 @@
+# standard imports
+import os
+import unittest
+import json
+import logging
+
+# third-party imports
+import web3
+import eth_tester
+import eth_abi
+
+logging.basicConfig(level=logging.DEBUG)
+logg = logging.getLogger()
+
+logging.getLogger('web3').setLevel(logging.WARNING)
+logging.getLogger('eth.vm').setLevel(logging.WARNING)
+
+testdir = os.path.dirname(__file__)
+
+
+class Test(unittest.TestCase):
+
+ contract = None
+
+ def setUp(self):
+ eth_params = eth_tester.backends.pyevm.main.get_default_genesis_params({
+ 'gas_limit': 9000000,
+ })
+
+ f = open(os.path.join(testdir, '../../solidity/Owned.bin'), 'r')
+ self.bytecode_owned = f.read()
+ f.close()
+
+ f = open(os.path.join(testdir, '../../solidity/Owned.json'), 'r')
+ self.abi_owned = json.load(f)
+ f.close()
+
+ f = open(os.path.join(testdir, '../../solidity/VoidOwner.bin'), 'r')
+ self.bytecode_void = f.read()
+ f.close()
+
+ f = open(os.path.join(testdir, '../../solidity/VoidOwner.json'), 'r')
+ self.abi_void = json.load(f)
+ f.close()
+
+ backend = eth_tester.PyEVMBackend(eth_params)
+ self.eth_tester = eth_tester.EthereumTester(backend)
+ provider = web3.Web3.EthereumTesterProvider(self.eth_tester)
+ self.w3 = web3.Web3(provider)
+
+ c = self.w3.eth.contract(abi=self.abi_owned, bytecode=self.bytecode_owned)
+ tx_hash = c.constructor().transact()
+ r = self.w3.eth.getTransactionReceipt(tx_hash)
+ self.assertEqual(r.status, 1)
+ self.contract_owned = self.w3.eth.contract(abi=self.abi_owned, address=r.contractAddress)
+
+ c = self.w3.eth.contract(abi=self.abi_void, bytecode=self.bytecode_void)
+ tx_hash = c.constructor().transact()
+ r = self.w3.eth.getTransactionReceipt(tx_hash)
+ self.assertEqual(r.status, 1)
+ self.contract_void = self.w3.eth.contract(abi=self.abi_void, address=r.contractAddress)
+
+
+ def tearDown(self):
+ pass
+
+
+ def test_hello(self):
+ owner = self.contract_owned.functions.owner().call()
+ self.assertEqual(self.w3.eth.accounts[0], owner)
+
+
+ def test_accept(self):
+ owner = self.contract_owned.functions.owner().call()
+
+ tx_hash = self.contract_owned.functions.transferOwnership(self.contract_void.address).transact()
+ r = self.w3.eth.getTransactionReceipt(tx_hash)
+ self.assertEqual(r.status, 1)
+
+ tx_hash = self.contract_void.functions.omNom(self.contract_owned.address).transact()
+ r = self.w3.eth.getTransactionReceipt(tx_hash)
+ self.assertEqual(r.status, 1)
+ logged = False
+ for l in r.logs:
+ logg.debug('log {}'.format(l))
+ if l.topics[0].hex() == '0xdc3c82f4776932041f15a08f769aadd6ed44c2a975e64bbf0fde8cf812f8b6b8':
+ matchLogAddress = '0x{:>064}'.format(self.contract_owned.address[2:].lower()
+ self.assertEqual(l.data, matchLogAddress))
+ logged = True
+
+ self.assertTrue(logged)
+
+ owner = self.contract_owned.functions.owner().call()
+ self.assertEqual(owner, self.contract_void.address)
+
+ tx = self.contract_owned.functions.transferOwnership(self.contract_void.address)
+ self.assertRaises(eth_tester.exceptions.TransactionFailed, tx.transact)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/solidity/Makefile b/solidity/Makefile
@@ -0,0 +1,18 @@
+SOLC = /usr/bin/solc
+
+all:
+ $(SOLC) VoidOwner.sol --abi --evm-version byzantium | awk 'NR>3' > VoidOwner.json
+ $(SOLC) VoidOwner.sol --bin --evm-version byzantium | awk 'NR>3' > VoidOwner.bin
+ truncate -s -1 VoidOwner.bin
+ $(SOLC) Owned.sol --abi --evm-version byzantium | awk 'NR>3' > Owned.json
+ $(SOLC) Owned.sol --bin --evm-version byzantium | awk 'NR>3' > Owned.bin
+ truncate -s -1 Owned.bin
+
+test: all
+ python ../python/tests/test_basic.py
+
+install: all
+ cp -v VoidOwner.{json,bin} ../python/void_owner/data/
+ cp -v Owned.{json,bin} ../python/void_owner/data/
+
+.PHONY: test install
diff --git a/solidity/Owned.sol b/solidity/Owned.sol
@@ -0,0 +1,32 @@
+pragma solidity >= 0.6.11;
+
+contract Owned {
+
+ // EIP173
+ address public owner;
+
+ address newOwner;
+
+ // EIP173
+ event OwnershipTransferred(address indexed _previousOwner, address indexed _newOwner);
+
+ constructor() public {
+ owner = msg.sender;
+ }
+
+ // EIP173
+ function transferOwnership(address _newOwner) public returns (bool) {
+ require(owner == msg.sender);
+ newOwner = _newOwner;
+ }
+
+ function acceptOwnership() public returns (bool) {
+ address oldOwner;
+
+ require(newOwner == msg.sender);
+ oldOwner = owner;
+ owner = newOwner;
+ emit OwnershipTransferred(oldOwner, owner);
+ return true;
+ }
+}
diff --git a/solidity/VoidOwner.sol b/solidity/VoidOwner.sol
@@ -0,0 +1,23 @@
+pragma solidity >=0.6.11;
+
+contract VoidOwner {
+
+ event OwnershipTaken(address _result);
+
+ function omNom(address _contract) public returns (bool) {
+ bool ok;
+ bytes memory result;
+ address newOwner;
+
+ (ok, result) = _contract.call(abi.encodeWithSignature("acceptOwnership()"));
+ require(ok, "ERR_ACCEPT");
+
+ (ok, result) = _contract.call(abi.encodeWithSignature("owner()"));
+ require(ok, "ERR_INTERFACE");
+ newOwner = abi.decode(result, (address));
+ require(address(this) == newOwner);
+
+ emit OwnershipTaken(_contract);
+ return ok;
+ }
+}