From ef3ee7caf0d0e7a8a5a44908cda6bb5ab306ea7a Mon Sep 17 00:00:00 2001 From: lash Date: Tue, 6 Jun 2023 15:27:41 +0100 Subject: [PATCH] Add minter and burner python interface and test code --- python/eth_burner/__init__.py | 1 + python/eth_burner/burn.py | 33 +++++++++++++++ python/eth_burner/unittest/__init__.py | 1 + python/eth_burner/unittest/base.py | 53 +++++++++++++++++++++++++ python/eth_burner/unittest/interface.py | 19 +++++++++ python/eth_expire/unittest/base.py | 5 --- python/eth_minter/__init__.py | 1 + python/eth_minter/minter.py | 25 ++++++++++++ python/eth_minter/unittest/__init__.py | 1 + python/eth_minter/unittest/base.py | 51 ++++++++++++++++++++++++ python/eth_minter/unittest/interface.py | 19 +++++++++ python/solidity/BurnerTest.bin | 1 + python/solidity/BurnerTest.sol | 50 +++++++++++++++++++++++ python/solidity/ExpireTest.bin | 2 +- python/solidity/ExpireTest.sol | 2 +- python/solidity/MinterTest.bin | 1 + python/solidity/MinterTest.sol | 35 ++++++++++++++++ python/tests/test_burner.py | 29 ++++++++++++++ python/tests/test_minter.py | 29 ++++++++++++++ solidity/Burner.sol | 5 ++- 20 files changed, 354 insertions(+), 9 deletions(-) create mode 100644 python/eth_burner/__init__.py create mode 100644 python/eth_burner/burn.py create mode 100644 python/eth_burner/unittest/__init__.py create mode 100644 python/eth_burner/unittest/base.py create mode 100644 python/eth_burner/unittest/interface.py create mode 100644 python/eth_minter/__init__.py create mode 100644 python/eth_minter/minter.py create mode 100644 python/eth_minter/unittest/__init__.py create mode 100644 python/eth_minter/unittest/base.py create mode 100644 python/eth_minter/unittest/interface.py create mode 100644 python/solidity/BurnerTest.bin create mode 100644 python/solidity/BurnerTest.sol create mode 100644 python/solidity/MinterTest.bin create mode 100644 python/solidity/MinterTest.sol create mode 100644 python/tests/test_burner.py create mode 100644 python/tests/test_minter.py diff --git a/python/eth_burner/__init__.py b/python/eth_burner/__init__.py new file mode 100644 index 0000000..49988b6 --- /dev/null +++ b/python/eth_burner/__init__.py @@ -0,0 +1 @@ +from .burn import EthBurner diff --git a/python/eth_burner/burn.py b/python/eth_burner/burn.py new file mode 100644 index 0000000..54759b7 --- /dev/null +++ b/python/eth_burner/burn.py @@ -0,0 +1,33 @@ +# 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 EthBurner(TxFactory): + + def burn(self, contract_address, sender_address, value, tx_format=TxFormat.JSONRPC): + enc = ABIContractEncoder() + enc.method('burn') + enc.typ(ABIContractType.UINT256) + enc.uint256(value) + 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 + + + def burn_all(self, contract_address, sender_address, tx_format=TxFormat.JSONRPC): + enc = ABIContractEncoder() + enc.method('burn') + 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/eth_burner/unittest/__init__.py b/python/eth_burner/unittest/__init__.py new file mode 100644 index 0000000..1033477 --- /dev/null +++ b/python/eth_burner/unittest/__init__.py @@ -0,0 +1 @@ +from .interface import TestEthBurnerInterface diff --git a/python/eth_burner/unittest/base.py b/python/eth_burner/unittest/base.py new file mode 100644 index 0000000..71619e4 --- /dev/null +++ b/python/eth_burner/unittest/base.py @@ -0,0 +1,53 @@ +# standard imports +import os +import logging +import datetime + +# 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_burner import EthBurner + +script_dir = os.path.dirname(os.path.realpath(__file__)) +contract_dir = os.path.join(script_dir, '..', '..', 'solidity') + +logg = logging.getLogger(__name__) + + +class TestEthBurner(EthTesterCase): + + def setUp(self): + super(TestEthBurner, self).setUp() + + self.conn = RPCConnection.connect(self.chain_spec, 'default') + nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) + + f = open(os.path.join(contract_dir, 'BurnerTest.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.initial_supply = 1024 + enc = ABIContractEncoder() + enc = ABIContractEncoder() + enc.uint256(self.initial_supply) + args = enc.get() + + tx = txf.set_code(tx, code + args) + (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 burner test contract with hash {}'.format(r)) diff --git a/python/eth_burner/unittest/interface.py b/python/eth_burner/unittest/interface.py new file mode 100644 index 0000000..ac0f488 --- /dev/null +++ b/python/eth_burner/unittest/interface.py @@ -0,0 +1,19 @@ +# external imports +from chainlib.eth.tx import receipt +from chainlib.eth.nonce import RPCNonceOracle + +# local imports +from eth_burner import EthBurner + + +class TestEthBurnerInterface: + + def test_supply(self): + self.alice = self.accounts[1] + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = EthBurner(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.burn(self.address, self.accounts[0], int(self.initial_supply / 2)) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'],1) diff --git a/python/eth_expire/unittest/base.py b/python/eth_expire/unittest/base.py index de58edf..23e935a 100644 --- a/python/eth_expire/unittest/base.py +++ b/python/eth_expire/unittest/base.py @@ -13,9 +13,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') @@ -27,8 +24,6 @@ class TestEthExpire(EthTesterCase): def setUp(self): super(TestEthExpire, self).setUp() - self.set_method = None - self.conn = RPCConnection.connect(self.chain_spec, 'default') nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) diff --git a/python/eth_minter/__init__.py b/python/eth_minter/__init__.py new file mode 100644 index 0000000..3f54f72 --- /dev/null +++ b/python/eth_minter/__init__.py @@ -0,0 +1 @@ +from .minter import EthMinter diff --git a/python/eth_minter/minter.py b/python/eth_minter/minter.py new file mode 100644 index 0000000..ff05c53 --- /dev/null +++ b/python/eth_minter/minter.py @@ -0,0 +1,25 @@ +# 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 EthMinter(TxFactory): + + def mint_to(self, contract_address, sender_address, recipient_address, value, tx_format=TxFormat.JSONRPC): + enc = ABIContractEncoder() + enc.method('mintTo') + enc.typ(ABIContractType.ADDRESS) + enc.typ(ABIContractType.UINT256) + enc.address(recipient_address) + enc.uint256(value) + 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/eth_minter/unittest/__init__.py b/python/eth_minter/unittest/__init__.py new file mode 100644 index 0000000..56f5648 --- /dev/null +++ b/python/eth_minter/unittest/__init__.py @@ -0,0 +1 @@ +from .interface import TestEthMinterInterface diff --git a/python/eth_minter/unittest/base.py b/python/eth_minter/unittest/base.py new file mode 100644 index 0000000..559a5a8 --- /dev/null +++ b/python/eth_minter/unittest/base.py @@ -0,0 +1,51 @@ +# standard imports +import os +import logging +import datetime + +# 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_minter import EthMinter + +script_dir = os.path.dirname(os.path.realpath(__file__)) +contract_dir = os.path.join(script_dir, '..', '..', 'solidity') + +logg = logging.getLogger(__name__) + + +class TestEthMinter(EthTesterCase): + + def setUp(self): + super(TestEthMinter, self).setUp() + + self.conn = RPCConnection.connect(self.chain_spec, 'default') + nonce_oracle = RPCNonceOracle(self.accounts[0], self.conn) + + f = open(os.path.join(contract_dir, 'MinterTest.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.initial_supply = 1024 + enc = ABIContractEncoder() + args = enc.get() + + tx = txf.set_code(tx, code + args) + (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 minter test contract with hash {}'.format(r)) diff --git a/python/eth_minter/unittest/interface.py b/python/eth_minter/unittest/interface.py new file mode 100644 index 0000000..a912c6f --- /dev/null +++ b/python/eth_minter/unittest/interface.py @@ -0,0 +1,19 @@ +# external imports +from chainlib.eth.tx import receipt +from chainlib.eth.nonce import RPCNonceOracle + +# local imports +from eth_minter import EthMinter + + +class TestEthMinterInterface: + + def test_supply(self): + self.alice = self.accounts[1] + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = EthMinter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.alice, self.initial_supply) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'],1) diff --git a/python/solidity/BurnerTest.bin b/python/solidity/BurnerTest.bin new file mode 100644 index 0000000..af1b5e3 --- /dev/null +++ b/python/solidity/BurnerTest.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b5060405161070438038061070483398181016040528101906100329190610081565b8060008190555080600281905550506100ae565b600080fd5b6000819050919050565b61005e8161004b565b811461006957600080fd5b50565b60008151905061007b81610055565b92915050565b60006020828403121561009757610096610046565b5b60006100a58482850161006c565b91505092915050565b610647806100bd6000396000f3fe608060405234801561001057600080fd5b506004361061007f576000357c01000000000000000000000000000000000000000000000000000000009004806301ffc9a71461008457806342966c68146100b457806344d17187146100e457806344df8e7014610100578063a2309ff81461011e578063d89135cd1461013c575b600080fd5b61009e60048036038101906100999190610353565b61015a565b6040516100ab919061039b565b60405180910390f35b6100ce60048036038101906100c991906103ec565b61020a565b6040516100db919061039b565b60405180910390f35b6100fe60048036038101906100f991906104dc565b61021f565b005b61010861022f565b604051610115919061055f565b60405180910390f35b610126610241565b604051610133919061055f565b60405180910390f35b610144610247565b604051610151919061055f565b60405180910390f35b60006301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036101ae5760019050610205565b63bc4babdd7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036102005760019050610205565b600090505b919050565b60006102158261024d565b5060019050919050565b6102288361020a565b5050505050565b600061023c60005461024d565b905090565b60005481565b60015481565b6000808260025461025e91906105a9565b101561026957600080fd5b816001600082825461027b91906105dd565b92505081905550816002600082825461029491906105a9565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040516102e1919061055f565b60405180910390a2819050919050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610330816102fb565b811461033b57600080fd5b50565b60008135905061034d81610327565b92915050565b600060208284031215610369576103686102f1565b5b60006103778482850161033e565b91505092915050565b60008115159050919050565b61039581610380565b82525050565b60006020820190506103b0600083018461038c565b92915050565b6000819050919050565b6103c9816103b6565b81146103d457600080fd5b50565b6000813590506103e6816103c0565b92915050565b600060208284031215610402576104016102f1565b5b6000610410848285016103d7565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061044482610419565b9050919050565b61045481610439565b811461045f57600080fd5b50565b6000813590506104718161044b565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261049c5761049b610477565b5b8235905067ffffffffffffffff8111156104b9576104b861047c565b5b6020830191508360018202830111156104d5576104d4610481565b5b9250929050565b600080600080606085870312156104f6576104f56102f1565b5b600061050487828801610462565b9450506020610515878288016103d7565b935050604085013567ffffffffffffffff811115610536576105356102f6565b5b61054287828801610486565b925092505092959194509250565b610559816103b6565b82525050565b60006020820190506105746000830184610550565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006105b4826103b6565b91506105bf836103b6565b92508282039050818111156105d7576105d661057a565b5b92915050565b60006105e8826103b6565b91506105f3836103b6565b925082820190508082111561060b5761060a61057a565b5b9291505056fea2646970667358221220cf04ca2f9a9ef1aee6a7109799862035ae01e772554ee9c71f0ca5243159197164736f6c63430008130033 \ No newline at end of file diff --git a/python/solidity/BurnerTest.sol b/python/solidity/BurnerTest.sol new file mode 100644 index 0000000..f7143c9 --- /dev/null +++ b/python/solidity/BurnerTest.sol @@ -0,0 +1,50 @@ +pragma solidity >=0.6.3; + +// Author: Louis Holbrook 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 +// SPDX-License-Identifier: AGPL-3.0-or-later + +contract MinterTest { + uint256 public totalMinted; + uint256 public totalBurned; + uint256 balance; + + event Burn(address indexed _burner, uint256 _burned); + + constructor(uint256 _mintValue) { + totalMinted = _mintValue; + balance = _mintValue; + } + + function burn(address _from, uint256 _value, bytes calldata _data) public { + _from; + _data; + burn(_value); + } + + function burn(uint256 _value) public returns (bool) { + burnCore(_value); + return true; + } + + function burnCore(uint256 _value) internal returns(uint256) { + require(balance - _value >= 0); + totalBurned += _value; + balance -= _value; + emit Burn(msg.sender, _value); + return _value; + } + + function burn() public returns (uint256) { + return burnCore(totalMinted); + } + + function supportsInterface(bytes4 _sum) public pure returns (bool) { + if (_sum == 0x01ffc9a7) { // EIP165 + return true; + } + if (_sum == 0xbc4babdd) { // Burner + return true; + } + return false; + } +} diff --git a/python/solidity/ExpireTest.bin b/python/solidity/ExpireTest.bin index 716efa8..c0f1501 100644 --- a/python/solidity/ExpireTest.bin +++ b/python/solidity/ExpireTest.bin @@ -1 +1 @@ -608060405234801561001057600080fd5b506040516105143803806105148339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b61045e806100b66000396000f3fe608060405234801561001057600080fd5b5060043610610069576000357c01000000000000000000000000000000000000000000000000000000009004806301cceb381461006e57806301ffc9a71461008a5780635f408c04146100ba578063b1cb0db3146100d8575b600080fd5b610088600480360381019061008391906102df565b6100f6565b005b6100a4600480360381019061009f9190610364565b610162565b6040516100b191906103ac565b60405180910390f35b6100c2610212565b6040516100cf91906103e3565b60405180910390f35b6100e061029e565b6040516100ed919061040d565b60405180910390f35b600160009054906101000a900460ff161561011057600080fd5b600054811161011e57600080fd5b6000547ff5bd6cb27a0006b5ea8618058a0d84719695cb6d984f4840bc1a54ca12ae4b7c82604051610150919061040d565b60405180910390a28060008190555050565b60006301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036101b6576001905061020d565b63841a0e947c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610208576001905061020d565b600090505b919050565b6000600160009054906101000a900460ff1615610232576001905061029b565b600054421015610245576000905061029b565b60018060006101000a81548160ff0219169083151502179055507ff80dbaea4785589e52984ca36a31de106adc77759539a5c7d92883bf49692fe94260405161028e919061040d565b60405180910390a1600190505b90565b60005481565b600080fd5b6000819050919050565b6102bc816102a9565b81146102c757600080fd5b50565b6000813590506102d9816102b3565b92915050565b6000602082840312156102f5576102f46102a4565b5b6000610303848285016102ca565b91505092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6103418161030c565b811461034c57600080fd5b50565b60008135905061035e81610338565b92915050565b60006020828403121561037a576103796102a4565b5b60006103888482850161034f565b91505092915050565b60008115159050919050565b6103a681610391565b82525050565b60006020820190506103c1600083018461039d565b92915050565b600060ff82169050919050565b6103dd816103c7565b82525050565b60006020820190506103f860008301846103d4565b92915050565b610407816102a9565b82525050565b600060208201905061042260008301846103fe565b9291505056fea26469706673582212200ea18a383a2b4a17a3ce884a7787899f37d703ede95cd1ba000e15710432f90b64736f6c63430008130033 \ No newline at end of file +608060405234801561001057600080fd5b506040516105143803806105148339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b61045e806100b66000396000f3fe608060405234801561001057600080fd5b5060043610610069576000357c01000000000000000000000000000000000000000000000000000000009004806301cceb381461006e57806301ffc9a71461008a5780635f408c04146100ba578063b1cb0db3146100d8575b600080fd5b610088600480360381019061008391906102df565b6100f6565b005b6100a4600480360381019061009f9190610364565b610162565b6040516100b191906103ac565b60405180910390f35b6100c2610212565b6040516100cf91906103e3565b60405180910390f35b6100e061029e565b6040516100ed919061040d565b60405180910390f35b600160009054906101000a900460ff161561011057600080fd5b600054811161011e57600080fd5b6000547ff5bd6cb27a0006b5ea8618058a0d84719695cb6d984f4840bc1a54ca12ae4b7c82604051610150919061040d565b60405180910390a28060008190555050565b60006301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036101b6576001905061020d565b63841a0e947c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610208576001905061020d565b600090505b919050565b6000600160009054906101000a900460ff1615610232576001905061029b565b600054421015610245576000905061029b565b60018060006101000a81548160ff0219169083151502179055507ff80dbaea4785589e52984ca36a31de106adc77759539a5c7d92883bf49692fe94260405161028e919061040d565b60405180910390a1600190505b90565b60005481565b600080fd5b6000819050919050565b6102bc816102a9565b81146102c757600080fd5b50565b6000813590506102d9816102b3565b92915050565b6000602082840312156102f5576102f46102a4565b5b6000610303848285016102ca565b91505092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6103418161030c565b811461034c57600080fd5b50565b60008135905061035e81610338565b92915050565b60006020828403121561037a576103796102a4565b5b60006103888482850161034f565b91505092915050565b60008115159050919050565b6103a681610391565b82525050565b60006020820190506103c1600083018461039d565b92915050565b600060ff82169050919050565b6103dd816103c7565b82525050565b60006020820190506103f860008301846103d4565b92915050565b610407816102a9565b82525050565b600060208201905061042260008301846103fe565b9291505056fea264697066735822122008d6e0c184036b44d56435108c0e081869b445ea32edbcd7035807691a26a11264736f6c63430008130033 \ No newline at end of file diff --git a/python/solidity/ExpireTest.sol b/python/solidity/ExpireTest.sol index 2657d57..8ba6020 100644 --- a/python/solidity/ExpireTest.sol +++ b/python/solidity/ExpireTest.sol @@ -38,7 +38,7 @@ contract ExpireTest { if (_sum == 0x01ffc9a7) { // EIP165 return true; } - if (_sum == 0x841a0e94) { // Capped + if (_sum == 0x841a0e94) { // Expire return true; } return false; diff --git a/python/solidity/MinterTest.bin b/python/solidity/MinterTest.bin new file mode 100644 index 0000000..bacf2cd --- /dev/null +++ b/python/solidity/MinterTest.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50610653806100206000396000f3fe608060405234801561001057600080fd5b5060043610610074576000357c01000000000000000000000000000000000000000000000000000000009004806301ffc9a714610079578063449a52f8146100a95780638832e6e3146100d957806394d008ef146100f5578063e3d670d714610111575b600080fd5b610093600480360381019061008e9190610353565b610141565b6040516100a0919061039b565b60405180910390f35b6100c360048036038101906100be919061044a565b6101f1565b6040516100d0919061039b565b60405180910390f35b6100f360048036038101906100ee91906104ef565b6102b7565b005b61010f600480360381019061010a91906104ef565b6102c8565b005b61012b60048036038101906101269190610563565b6102d9565b604051610138919061059f565b60405180910390f35b60006301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361019557600190506101ec565b635878bcf47c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036101e757600190506101ec565b600090505b919050565b6000816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461024191906105e9565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8846040516102a5919061059f565b60405180910390a36001905092915050565b6102c184846101f1565b5050505050565b6102d284846101f1565b5050505050565b60006020528060005260406000206000915090505481565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610330816102fb565b811461033b57600080fd5b50565b60008135905061034d81610327565b92915050565b600060208284031215610369576103686102f1565b5b60006103778482850161033e565b91505092915050565b60008115159050919050565b61039581610380565b82525050565b60006020820190506103b0600083018461038c565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006103e1826103b6565b9050919050565b6103f1816103d6565b81146103fc57600080fd5b50565b60008135905061040e816103e8565b92915050565b6000819050919050565b61042781610414565b811461043257600080fd5b50565b6000813590506104448161041e565b92915050565b60008060408385031215610461576104606102f1565b5b600061046f858286016103ff565b925050602061048085828601610435565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f8401126104af576104ae61048a565b5b8235905067ffffffffffffffff8111156104cc576104cb61048f565b5b6020830191508360018202830111156104e8576104e7610494565b5b9250929050565b60008060008060608587031215610509576105086102f1565b5b6000610517878288016103ff565b945050602061052887828801610435565b935050604085013567ffffffffffffffff811115610549576105486102f6565b5b61055587828801610499565b925092505092959194509250565b600060208284031215610579576105786102f1565b5b6000610587848285016103ff565b91505092915050565b61059981610414565b82525050565b60006020820190506105b46000830184610590565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006105f482610414565b91506105ff83610414565b9250828201905080821115610617576106166105ba565b5b9291505056fea2646970667358221220a5a810b6de36b1154b4b2d37d08d4e8a5fe442c870cd58cdba0d86a13da3dda964736f6c63430008130033 \ No newline at end of file diff --git a/python/solidity/MinterTest.sol b/python/solidity/MinterTest.sol new file mode 100644 index 0000000..3ba7d5e --- /dev/null +++ b/python/solidity/MinterTest.sol @@ -0,0 +1,35 @@ +pragma solidity >=0.6.3; + +// Author: Louis Holbrook 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 +// SPDX-License-Identifier: AGPL-3.0-or-later + +contract MinterTest { + mapping (address => uint256) public balance; + + event Mint(address indexed _minter, address indexed _beneficiary, uint256 _value); + + function mintTo(address _beneficiary, uint256 _value) public returns (bool) { + balance[_beneficiary] += _value; + emit Mint(msg.sender, _beneficiary, _value); + return true; + } + + function mint(address _beneficiary, uint256 _value, bytes calldata _data) public { + _data; + mintTo(_beneficiary, _value); + } + function safeMint(address _beneficiary, uint256 _value, bytes calldata _data) public { + _data; + mintTo(_beneficiary, _value); + } + + function supportsInterface(bytes4 _sum) public pure returns (bool) { + if (_sum == 0x01ffc9a7) { // EIP165 + return true; + } + if (_sum == 0x5878bcf4) { // Minter + return true; + } + return false; + } +} diff --git a/python/tests/test_burner.py b/python/tests/test_burner.py new file mode 100644 index 0000000..620e8e0 --- /dev/null +++ b/python/tests/test_burner.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_burner import EthBurner +from eth_burner.unittest import TestEthBurnerInterface +from eth_burner.unittest.base import TestEthBurner + + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + + +class TestBurnerBase(TestEthBurner, TestEthBurnerInterface, TestERC165): + + def setUp(self): + super(TestBurnerBase, self).setUp() + self.add_interface_check('bc4babdd') + + +if __name__ == '__main__': + unittest.main() diff --git a/python/tests/test_minter.py b/python/tests/test_minter.py new file mode 100644 index 0000000..32389c2 --- /dev/null +++ b/python/tests/test_minter.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_minter import EthMinter +from eth_minter.unittest import TestEthMinterInterface +from eth_minter.unittest.base import TestEthMinter + + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + + +class TestMinterBase(TestEthMinter, TestEthMinterInterface, TestERC165): + + def setUp(self): + super(TestMinterBase, self).setUp() + self.add_interface_check('5878bcf4') + + +if __name__ == '__main__': + unittest.main() diff --git a/solidity/Burner.sol b/solidity/Burner.sol index c41c316..43c2c2e 100644 --- a/solidity/Burner.sol +++ b/solidity/Burner.sol @@ -12,10 +12,11 @@ interface IBurner { function burn(address _from, uint256 _amount, bytes calldata _data) external; // Burn given amount of tokens held by signer. - function burn(uint256 _burn) external returns (bool); + function burn(uint256 _amount) external returns (bool); // Burn all tokens held by signer. - function burn() external returns (bool); + // Returns the amount of tokens burned. + function burn() external returns (uint256); // Total amount of tokens that have been burned. function totalBurned() external returns (uint256);