commit dccb16a7369805f53498cb2bc441d13141072118
parent 503317d1bff36dff67a8b8b630ccbace5281a629
Author: nolash <dev@holbrook.no>
Date: Tue, 23 Mar 2021 12:24:31 +0100
Implement chainlib for constructor, rehabilitate basic test
Diffstat:
8 files changed, 313 insertions(+), 257 deletions(-)
diff --git a/python/erc20_transfer_authorization/__init__.py b/python/erc20_transfer_authorization/__init__.py
@@ -1 +1 @@
-from .approval import TransferApproval
+from .transfer_authorization import TransferAuthorization
diff --git a/python/erc20_transfer_authorization/approval.py b/python/erc20_transfer_authorization/approval.py
@@ -1,71 +0,0 @@
-# Author: Louis Holbrook <dev@holbrook.no> 0826EDA1702D1E87C6E2875121D2E7BB88C2A746
-# SPDX-License-Identifier: GPL-3.0-or-later
-# File-version: 1
-# Description: Python interface to abi and bin files for faucet contracts
-
-# standard imports
-import logging
-import json
-import os
-
-logg = logging.getLogger(__name__)
-
-moddir = os.path.dirname(__file__)
-datadir = os.path.join(moddir, 'data')
-
-
-class TransferApproval:
-
- __abi = None
- __bytecode = None
- __address = None
-
- def __init__(self, w3, address, signer_address=None):
- abi = TransferApproval.abi()
- TransferApproval.bytecode()
- self.__address = address
- self.contract = w3.eth.contract(abi=abi, address=address)
- self.w3 = w3
- if signer_address != None:
- self.signer_address = signer_address
- else:
- if type(self.w3.eth.defaultAccount).__name__ == 'Empty':
- self.w3.eth.defaultAccount = self.w3.eth.accounts[0]
- self.signer_address = self.w3.eth.defaultAccount
-
-
- @staticmethod
- def abi():
- if TransferApproval.__abi == None:
- f = open(os.path.join(datadir, 'TransferApproval.json'), 'r')
- TransferApproval.__abi = json.load(f)
- f.close()
- return TransferApproval.__abi
-
-
- @staticmethod
- def bytecode():
- if TransferApproval.__bytecode == None:
- f = open(os.path.join(datadir, 'TransferApproval.bin'))
- TransferApproval.__bytecode = f.read()
- f.close()
- return TransferApproval.__bytecode
-
-
- def last_serial(self):
- return self.contract.functions.lastSerial().call()
-
-
- def next_serial(self):
- return self.contract.functions.nextSerial().call()
-
-
- def requests(self, idx):
- req = self.contract.functions.requests(idx).call()
- return {
- 'serial': req[0],
- 'sender': req[1],
- 'recipient': req[2],
- 'token': req[3],
- 'value': req[4],
- }
diff --git a/python/erc20_transfer_authorization/transfer_authorization.py b/python/erc20_transfer_authorization/transfer_authorization.py
@@ -0,0 +1,134 @@
+# Author: Louis Holbrook <dev@holbrook.no> 0826EDA1702D1E87C6E2875121D2E7BB88C2A746
+# SPDX-License-Identifier: GPL-3.0-or-later
+# File-version: 1
+# Description: Python interface to abi and bin files for faucet contracts
+
+# standard imports
+import logging
+import json
+import os
+
+# external imports
+from chainlib.eth.tx import TxFactory
+from chainlib.eth.constant import ZERO_ADDRESS
+from chainlib.eth.contract import (
+ ABIContractEncoder,
+ ABIContractDecoder,
+ ABIContractType,
+ abi_decode_single,
+ )
+from chainlib.jsonrpc import jsonrpc_template
+from hexathon import add_0x
+
+logg = logging.getLogger().getChild(__name__)
+
+moddir = os.path.dirname(__file__)
+datadir = os.path.join(moddir, 'data')
+
+
+class TransferAuthorization(TxFactory):
+
+ __abi = None
+ __bytecode = None
+
+
+ @staticmethod
+ def abi():
+ if TransferAuthorization.__abi == None:
+ f = open(os.path.join(datadir, 'ERC20TransferAuthorization.json'), 'r')
+ TransferAuthorization.__abi = json.load(f)
+ f.close()
+ return TransferAuthorization.__abi
+
+
+ @staticmethod
+ def bytecode():
+ if TransferAuthorization.__bytecode == None:
+ f = open(os.path.join(datadir, 'ERC20TransferAuthorization.bin'))
+ TransferAuthorization.__bytecode = f.read()
+ f.close()
+ return TransferAuthorization.__bytecode
+
+
+ def constructor(self, sender_address):
+ code = TransferAuthorization.bytecode()
+ tx = self.template(sender_address, None, use_nonce=True)
+ tx = self.set_code(tx, code)
+ return self.build(tx)
+
+
+ def signers(self, contract_address, signer_address, sender_address=ZERO_ADDRESS):
+ o = jsonrpc_template()
+ o['method'] = 'eth_call'
+ enc = ABIContractEncoder()
+ enc.method('signers')
+ enc.typ(ABIContractType.ADDRESS)
+ enc.address(signer_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))
+ o['params'].append('latest')
+ return o
+
+
+ def have_signer(self, contract_address, signer_address, sender_address=ZERO_ADDRESS):
+ return self.signers(contract_address, signer_address, sender_address)
+
+
+ @classmethod
+ def parse_signers(self, v):
+ return abi_decode_single(ABIContractType.BOOLEAN, v)
+
+
+ @classmethod
+ def parse_create_request_request(self, v):
+ v = strip_0x(v)
+ cursor = 0
+ enc = ABIContractEncoder()
+ enc.method('createRequest')
+ enc.typ(ABIContractType.ADDRESS)
+ enc.typ(ABIContractType.ADDRESS)
+ enc.typ(ABIContractType.ADDRESS)
+ enc.typ(ABIContractType.UINT256)
+ r = enc.get()
+ l = len(r)
+ m = v[:l]
+ if m != r:
+ logg.error('method mismatch, expected {}, got {}'.format(r, m))
+ raise RequestMismatchException(v)
+ cursor += l
+
+ dec = ABIContractDecoder()
+ dec.typ(ABIContractType.ADDRESS)
+ dec.typ(ABIContractType.ADDRESS)
+ dec.typ(ABIContractType.ADDRESS)
+ dec.typ(ABIContractType.UINT256)
+ dec.val(v[cursor:cursor+64])
+ cursor += 64
+ dec.val(v[cursor:cursor+64])
+ cursor += 64
+ dec.val(v[cursor:cursor+64])
+ cursor += 64
+ dec.val(v[cursor:cursor+64])
+ r = dec.decode()
+ return r
+
+#
+# def last_serial(self):
+# return self.contract.functions.lastSerial().call()
+#
+#
+# def next_serial(self):
+# return self.contract.functions.nextSerial().call()
+#
+#
+# def requests(self, idx):
+# req = self.contract.functions.requests(idx).call()
+# return {
+# 'serial': req[0],
+# 'sender': req[1],
+# 'recipient': req[2],
+# 'token': req[3],
+# 'value': req[4],
+# }
diff --git a/python/requirements.txt b/python/requirements.txt
@@ -1,2 +1,2 @@
-web3==5.12.2
-crypto-dev-signer==0.4.13rc3
+crypto-dev-signer==0.4.13rc4
+chainlib==0.0.1a27
diff --git a/python/setup.cfg b/python/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = erc20-transfer-authorization
-version = 0.3.0a11
+version = 0.3.1a1
description = Simple approval escrow for ERC20 spend approval
author = Louis Holbrook
author_email = dev@holbrook.no
@@ -28,8 +28,8 @@ packages =
erc20_transfer_authorization.runnable
install_requires =
web3==5.12.2
- crypto-dev-signer~=0.4.13rc2
- chainlib~=0.0.1a15
+ crypto-dev-signer~=0.4.13rc4
+ chainlib~=0.0.1a27
[options.package_data]
* =
diff --git a/python/test_requirements.txt b/python/test_requirements.txt
@@ -1,2 +1,3 @@
-eth-tester==0.5.0b2
+eth-tester==0.5.0b3
py-evm==0.3.0a20
+#giftable-erc20-token==0.0.7b13
diff --git a/python/tests/base.py b/python/tests/base.py
@@ -1,11 +1,17 @@
+# standard imports
import os
import unittest
import json
import logging
-import web3
-import eth_tester
-import eth_abi
+# external imports
+from chainlib.eth.unittest.ethtester import EthTesterCase
+from chainlib.eth.nonce import RPCNonceOracle
+from chainlib.eth.tx import receipt
+from giftable_erc20_token import GiftableToken
+
+# local imports
+from erc20_transfer_authorization import TransferAuthorization
logging.basicConfig(level=logging.DEBUG)
logg = logging.getLogger()
@@ -16,56 +22,28 @@ logging.getLogger('eth.vm').setLevel(logging.WARNING)
testdir = os.path.dirname(__file__)
-class TestBase(unittest.TestCase):
-
- contract = None
+class TestBase(EthTesterCase):
def setUp(self):
- eth_params = eth_tester.backends.pyevm.main.get_default_genesis_params({
- 'gas_limit': 9000000,
- })
-
- f = open(os.path.join(testdir, '../erc20_transfer_authorization/data/ERC20TransferAuthorization.bin'), 'r')
- bytecode = f.read()
- f.close()
-
- f = open(os.path.join(testdir, '../erc20_transfer_authorization/data/ERC20TransferAuthorization.json'), 'r')
- self.abi_wallet = 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_wallet, bytecode=bytecode)
- tx_hash = c.constructor().transact({'from': self.w3.eth.accounts[0]})
-
- r = self.w3.eth.getTransactionReceipt(tx_hash)
-
- self.address_wallet = r.contractAddress
-
-
- f = open(os.path.join(testdir, '../erc20_transfer_authorization/data/GiftableToken.bin'), 'r')
- bytecode = f.read()
- f.close()
-
- f = open(os.path.join(testdir, '../erc20_transfer_authorization/data/GiftableToken.json'), 'r')
- self.abi_token = json.load(f)
- f.close()
+ super(TestBase, self).setUp()
+ nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
+ c = TransferAuthorization(signer=self.signer, nonce_oracle=nonce_oracle, chain_id=self.chain_spec.chain_id())
+ (tx_hash_hex, o) = c.constructor(self.accounts[0])
- c = self.w3.eth.contract(abi=self.abi_token, bytecode=bytecode)
- tx_hash = c.constructor('Foo Token', 'FOO', 18).transact({'from': self.w3.eth.accounts[0]})
+ self.rpc.do(o)
- r = self.w3.eth.getTransactionReceipt(tx_hash)
+ o = receipt(tx_hash_hex)
+ r = self.rpc.do(o)
+ self.assertEqual(r['status'], 1)
- self.address_token = r.contractAddress
- c = self.w3.eth.contract(abi=self.abi_token, address=self.address_token)
+ self.address = r['contract_address']
- tx_hash = c.functions.mint(1000).transact({'from': self.w3.eth.accounts[0]})
- tx_hash = c.functions.transfer(self.w3.eth.accounts[1], 100).transact({'from': self.w3.eth.accounts[0]})
- tx_hash = c.functions.transfer(self.w3.eth.accounts[2], 100).transact({'from': self.w3.eth.accounts[0]})
- tx_hash = c.functions.transfer(self.w3.eth.accounts[4], 100).transact({'from': self.w3.eth.accounts[0]})
+ c = GiftableToken(signer=self.signer, nonce_oracle=nonce_oracle, chain_id=self.chain_spec.chain_id())
+ (tx_hash_hex, o) = c.constructor(self.accounts[0], 'FooToken', 'FOO', 6)
+ self.rpc.do(o)
+ o = receipt(tx_hash_hex)
+ r = self.rpc.do(o)
+ self.assertEqual(r['status'], 1)
- def tearDown(self):
- pass
+ self.token_address = r['contract_address']
diff --git a/python/tests/test_app.py b/python/tests/test_app.py
@@ -3,6 +3,12 @@ import os
import unittest
import logging
+# external imports
+from chainlib.eth.nonce import RPCNonceOracle
+
+# local imports
+from erc20_transfer_authorization import TransferAuthorization
+
# testutil imports
from tests.base import TestBase
@@ -14,137 +20,145 @@ testdir = os.path.dirname(__file__)
class ERC20TransferAuthorizationBasicTest(TestBase):
def test_basic(self):
- c = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet)
- self.assertTrue(c.functions.signers(self.w3.eth.accounts[0]).call())
- self.assertFalse(c.functions.signers(self.w3.eth.accounts[1]).call())
-
-
- def test_get(self):
- w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet)
- t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token)
-
- tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 10).transact({'from': self.w3.eth.accounts[9]})
- r = self.w3.eth.getTransactionReceipt(tx_hash)
-
- topic_match = 'b609ae609609ee99268d05bc1371102cafe8d6b964bf082439ab16be2a01c87c'
- log = r.logs[0]
- topic = log.topics[0]
- self.assertEqual(topic.hex()[2:], topic_match)
- serial = int(log.data[66:], 16)
-
- for i in range(1, 3):
- tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3+i], t.address, 10*(i+1)).transact({'from': self.w3.eth.accounts[2]})
-
- tq_count = w.functions.count().call()
- assert (tq_count == 3);
-
- for i in range(w.functions.nextSerial().call(), w.functions.lastSerial().call()):
- tqg = w.functions.requests(i).call()
-
- self.assertEqual(tqg[0], i)
- self.assertEqual(tqg[1], self.w3.eth.accounts[2])
- self.assertEqual(tqg[2], self.w3.eth.accounts[3+(i-1)])
- self.assertEqual(tqg[3], t.address)
- self.assertEqual(tqg[4], 10*i)
-
-
- def test_get_vote(self):
- w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet)
- t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token)
-
- tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 10).transact({'from': self.w3.eth.accounts[9]})
- w.functions.nay(1).transact({'from': self.w3.eth.accounts[0]})
-
- self.assertEqual(w.functions.voters(1, 0).call(), self.w3.eth.accounts[0])
- self.assertEqual(w.functions.vote(1, self.w3.eth.accounts[0]).call(), -1)
-
-
- def test_indexes(self):
- w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet)
- t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token)
-
- for i in range(0, 5):
- amount = 10*(i+1)
- sender = self.w3.eth.accounts[3+i];
- tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], sender, t.address, amount).transact({'from': self.w3.eth.accounts[2]})
-
- w.functions.nay(1).transact({'from': self.w3.eth.accounts[0]})
- w.functions.nay(4).transact({'from': self.w3.eth.accounts[0]})
-
- self.assertEqual(w.functions.getSerialAt(0).call(), 2)
- self.assertEqual(w.functions.getSerialAt(1).call(), 3)
- self.assertEqual(w.functions.getSerialAt(2).call(), 5)
-
-
- def test_index_after_removal(self):
- w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet)
- t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token)
-
- for i in range(0, 4):
- amount = 10*(i+1)
- sender = self.w3.eth.accounts[3+i];
- tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], sender, t.address, amount).transact({'from': self.w3.eth.accounts[2]})
-
- tq_count = w.functions.count().call()
- self.assertEqual(tq_count, 4);
- self.assertEqual(w.functions.lastSerial().call(), 4)
- self.assertEqual(w.functions.nextSerial().call(), 1)
-
- w.functions.nay(2).transact({'from': self.w3.eth.accounts[0]})
- self.assertEqual(w.functions.count().call(), 3)
- self.assertEqual(w.functions.nextSerial().call(), 1)
- self.assertEqual(w.functions.lastSerial().call(), 4)
-
- w.functions.nay(1).transact({'from': self.w3.eth.accounts[0]})
- self.assertEqual(w.functions.count().call(), 2)
- self.assertEqual(w.functions.nextSerial().call(), 3)
- self.assertEqual(w.functions.lastSerial().call(), 4)
-
- w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 42).transact({'from': self.w3.eth.accounts[2]})
- self.assertEqual(w.functions.count().call(), 3)
- self.assertEqual(w.functions.lastSerial().call(), 5)
- self.assertEqual(w.functions.nextSerial().call(), 3)
-
- w.functions.nay(3).transact({'from': self.w3.eth.accounts[0]})
- self.assertEqual(w.functions.count().call(), 2)
- self.assertEqual(w.functions.lastSerial().call(), 5)
- self.assertEqual(w.functions.nextSerial().call(), 4)
-
- w.functions.nay(4).transact({'from': self.w3.eth.accounts[0]})
- self.assertEqual(w.functions.count().call(), 1)
- self.assertEqual(w.functions.nextSerial().call(), 5)
- self.assertEqual(w.functions.lastSerial().call(), 5)
-
- w.functions.nay(5).transact({'from': self.w3.eth.accounts[0]})
- self.assertEqual(w.functions.count().call(), 0)
- self.assertEqual(w.functions.nextSerial().call(), 0)
- self.assertEqual(w.functions.lastSerial().call(), 5)
-
-
- def test_pass_on_insufficient_approve(self):
- w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet)
- t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token)
-
- self.eth_tester.mine_block()
-
- w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 10).transact({'from': self.w3.eth.accounts[2]})
- w.functions.yay(1).transact({'from': self.w3.eth.accounts[0]})
- self.eth_tester.mine_block()
-
- tx_hash = w.functions.executeRequest(1).transact({'from': self.w3.eth.accounts[0]})
-
- r = self.w3.eth.getTransactionReceipt(tx_hash)
-
- topic_match = 'dab20a0fcd702cf875c2d715d5c3fc99af66a716c94b3405408c94b7311c99eb' # TransferFail(uint256)
- log = r.logs[0]
- topic = log.topics[0]
- self.assertEqual(topic.hex()[2:], topic_match)
- serial = int(log.data[2:], 16)
-
- self.assertEqual(serial, 1)
-
- self.assertEqual(w.functions.count().call(), 0)
- self.assertEqual(w.functions.nextSerial().call(), 0)
+
+ nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
+ c = TransferAuthorization(chain_id=self.chain_spec.chain_id())
+
+ o = c.signers(self.address, self.accounts[0], sender_address=self.accounts[0])
+ r = self.rpc.do(o)
+ self.assertTrue(c.parse_signers(r))
+
+ o = c.signers(self.address, self.accounts[1], sender_address=self.accounts[0])
+ r = self.rpc.do(o)
+ self.assertFalse(c.parse_signers(r))
+
+
+# def test_get(self):
+# w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet)
+# t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token)
+#
+# tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 10).transact({'from': self.w3.eth.accounts[9]})
+# r = self.w3.eth.getTransactionReceipt(tx_hash)
+#
+# topic_match = 'b609ae609609ee99268d05bc1371102cafe8d6b964bf082439ab16be2a01c87c'
+# log = r.logs[0]
+# topic = log.topics[0]
+# self.assertEqual(topic.hex()[2:], topic_match)
+# serial = int(log.data[66:], 16)
+#
+# for i in range(1, 3):
+# tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3+i], t.address, 10*(i+1)).transact({'from': self.w3.eth.accounts[2]})
+#
+# tq_count = w.functions.count().call()
+# assert (tq_count == 3);
+#
+# for i in range(w.functions.nextSerial().call(), w.functions.lastSerial().call()):
+# tqg = w.functions.requests(i).call()
+#
+# self.assertEqual(tqg[0], i)
+# self.assertEqual(tqg[1], self.w3.eth.accounts[2])
+# self.assertEqual(tqg[2], self.w3.eth.accounts[3+(i-1)])
+# self.assertEqual(tqg[3], t.address)
+# self.assertEqual(tqg[4], 10*i)
+#
+#
+# def test_get_vote(self):
+# w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet)
+# t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token)
+#
+# tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 10).transact({'from': self.w3.eth.accounts[9]})
+# w.functions.nay(1).transact({'from': self.w3.eth.accounts[0]})
+#
+# self.assertEqual(w.functions.voters(1, 0).call(), self.w3.eth.accounts[0])
+# self.assertEqual(w.functions.vote(1, self.w3.eth.accounts[0]).call(), -1)
+#
+#
+# def test_indexes(self):
+# w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet)
+# t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token)
+#
+# for i in range(0, 5):
+# amount = 10*(i+1)
+# sender = self.w3.eth.accounts[3+i];
+# tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], sender, t.address, amount).transact({'from': self.w3.eth.accounts[2]})
+#
+# w.functions.nay(1).transact({'from': self.w3.eth.accounts[0]})
+# w.functions.nay(4).transact({'from': self.w3.eth.accounts[0]})
+#
+# self.assertEqual(w.functions.getSerialAt(0).call(), 2)
+# self.assertEqual(w.functions.getSerialAt(1).call(), 3)
+# self.assertEqual(w.functions.getSerialAt(2).call(), 5)
+#
+#
+# def test_index_after_removal(self):
+# w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet)
+# t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token)
+#
+# for i in range(0, 4):
+# amount = 10*(i+1)
+# sender = self.w3.eth.accounts[3+i];
+# tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], sender, t.address, amount).transact({'from': self.w3.eth.accounts[2]})
+#
+# tq_count = w.functions.count().call()
+# self.assertEqual(tq_count, 4);
+# self.assertEqual(w.functions.lastSerial().call(), 4)
+# self.assertEqual(w.functions.nextSerial().call(), 1)
+#
+# w.functions.nay(2).transact({'from': self.w3.eth.accounts[0]})
+# self.assertEqual(w.functions.count().call(), 3)
+# self.assertEqual(w.functions.nextSerial().call(), 1)
+# self.assertEqual(w.functions.lastSerial().call(), 4)
+#
+# w.functions.nay(1).transact({'from': self.w3.eth.accounts[0]})
+# self.assertEqual(w.functions.count().call(), 2)
+# self.assertEqual(w.functions.nextSerial().call(), 3)
+# self.assertEqual(w.functions.lastSerial().call(), 4)
+#
+# w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 42).transact({'from': self.w3.eth.accounts[2]})
+# self.assertEqual(w.functions.count().call(), 3)
+# self.assertEqual(w.functions.lastSerial().call(), 5)
+# self.assertEqual(w.functions.nextSerial().call(), 3)
+#
+# w.functions.nay(3).transact({'from': self.w3.eth.accounts[0]})
+# self.assertEqual(w.functions.count().call(), 2)
+# self.assertEqual(w.functions.lastSerial().call(), 5)
+# self.assertEqual(w.functions.nextSerial().call(), 4)
+#
+# w.functions.nay(4).transact({'from': self.w3.eth.accounts[0]})
+# self.assertEqual(w.functions.count().call(), 1)
+# self.assertEqual(w.functions.nextSerial().call(), 5)
+# self.assertEqual(w.functions.lastSerial().call(), 5)
+#
+# w.functions.nay(5).transact({'from': self.w3.eth.accounts[0]})
+# self.assertEqual(w.functions.count().call(), 0)
+# self.assertEqual(w.functions.nextSerial().call(), 0)
+# self.assertEqual(w.functions.lastSerial().call(), 5)
+#
+#
+# def test_pass_on_insufficient_approve(self):
+# w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet)
+# t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token)
+#
+# self.eth_tester.mine_block()
+#
+# w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 10).transact({'from': self.w3.eth.accounts[2]})
+# w.functions.yay(1).transact({'from': self.w3.eth.accounts[0]})
+# self.eth_tester.mine_block()
+#
+# tx_hash = w.functions.executeRequest(1).transact({'from': self.w3.eth.accounts[0]})
+#
+# r = self.w3.eth.getTransactionReceipt(tx_hash)
+#
+# topic_match = 'dab20a0fcd702cf875c2d715d5c3fc99af66a716c94b3405408c94b7311c99eb' # TransferFail(uint256)
+# log = r.logs[0]
+# topic = log.topics[0]
+# self.assertEqual(topic.hex()[2:], topic_match)
+# serial = int(log.data[2:], 16)
+#
+# self.assertEqual(serial, 1)
+#
+# self.assertEqual(w.functions.count().call(), 0)
+# self.assertEqual(w.functions.nextSerial().call(), 0)
if __name__ == '__main__':