Compare commits

...

2 Commits

Author SHA1 Message Date
lash 4e8082a663
Implement missing have() method in contract 2023-08-03 09:55:06 +01:00
lash 83981d6018
Prevent duplicate removal of entries 2023-06-19 12:10:29 +01:00
8 changed files with 82 additions and 6 deletions

View File

@ -1,3 +1,5 @@
- 0.6.2
* Prevent double removal on index entry
- 0.6.1
* Update list tool to chainlib 0.4.x arg flags
* Skip listing of superseded tokens (reverse lookup does not match entry index)

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"AddressAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_symbol","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"AddressKey","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"AddressRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_writer","type":"address"}],"name":"WriterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_writer","type":"address"}],"name":"WriterDeleted","type":"event"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"activate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"add","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_writer","type":"address"}],"name":"addWriter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"addressOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"deactivate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_writer","type":"address"}],"name":"deleteWriter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_idx","type":"uint256"}],"name":"entry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"entryCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_idx","type":"uint256"}],"name":"identifier","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"identifierCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"identifierList","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"register","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"remove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_sum","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"AddressAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_symbol","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"AddressKey","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"AddressRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_writer","type":"address"}],"name":"WriterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_writer","type":"address"}],"name":"WriterDeleted","type":"event"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"activate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"add","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_writer","type":"address"}],"name":"addWriter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"addressOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"deactivate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_writer","type":"address"}],"name":"deleteWriter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_idx","type":"uint256"}],"name":"entry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"entryCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"have","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_idx","type":"uint256"}],"name":"identifier","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"identifierCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"identifierList","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"register","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"remove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_sum","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"time","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

File diff suppressed because one or more lines are too long

View File

@ -85,6 +85,18 @@ class TokenUniqueSymbolIndex(TxFactory):
return tx
def remove(self, contract_address, sender_address, address, tx_format=TxFormat.JSONRPC):
enc = ABIContractEncoder()
enc.method('remove')
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
def add_writer(self, contract_address, sender_address, address, tx_format=TxFormat.JSONRPC, id_generator=None):
enc = ABIContractEncoder()
enc.method('addWriter')

View File

@ -1,6 +1,6 @@
[metadata]
name = eth-token-index
version = 0.6.1
version = 0.6.3
description = Token symbol to address unique index
author = Louis Holbrook
author_email = dev@holbrook.no

View File

@ -7,6 +7,8 @@ import hashlib
# external imports
from chainlib.eth.unittest.ethtester import EthTesterCase
from chainlib.eth.constant import ZERO_ADDRESS
from chainlib.eth.address import is_same_address
from chainlib.eth.nonce import RPCNonceOracle
from chainlib.eth.tx import receipt
from chainlib.error import JSONRPCException
@ -70,7 +72,7 @@ class TestTokenUniqueSymbolIndex(EthTesterCase):
(tx_hash_hex, o) = c.register(self.address, self.accounts[0], self.foo_token_address)
self.rpc.do(o)
e = unpack(bytes.fromhex(strip_0x(o['params'][0])), self.chain_spec)
#e = unpack(bytes.fromhex(strip_0x(o['params'][0])), self.chain_spec)
o = receipt(tx_hash_hex)
r = self.rpc.do(o)
@ -92,6 +94,40 @@ class TestTokenUniqueSymbolIndex(EthTesterCase):
self.assertEqual(count, 1)
def test_remove(self):
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
c = TokenUniqueSymbolIndex(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
(tx_hash_hex, o) = c.register(self.address, self.accounts[0], self.foo_token_address)
self.rpc.do(o)
#e = unpack(bytes.fromhex(strip_0x(o['params'][0])), self.chain_spec)
(tx_hash_hex, o) = c.remove(self.address, self.accounts[0], self.foo_token_address)
self.rpc.do(o)
o = receipt(tx_hash_hex)
r = self.rpc.do(o)
self.assertEqual(r['status'], 1)
o = c.address_of(self.address, 'FOO', sender_address=self.accounts[0])
r = self.rpc.do(o)
address = c.parse_address_of(r)
self.assertTrue(is_same_address(address, ZERO_ADDRESS))
o = c.entry(self.address, 0, sender_address=self.accounts[0])
with self.assertRaises(JSONRPCException):
self.rpc.do(o)
o = c.entry_count(self.address, sender_address=self.accounts[0])
r = self.rpc.do(o)
count = c.parse_entry_count(r)
self.assertEqual(count, 0)
(tx_hash_hex, o) = c.remove(self.address, self.accounts[0], self.foo_token_address)
self.rpc.do(o)
o = receipt(tx_hash_hex)
r = self.rpc.do(o)
self.assertEqual(r['status'], 0)
def test_identifiers(self):
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
@ -216,7 +252,21 @@ class TestTokenUniqueSymbolIndex(EthTesterCase):
self.assertEqual(int(r, 16), 2)
def test_have(self):
c = AccountsIndex(self.chain_spec)
o = c.have(self.address, self.foo_token_address, sender_address=self.accounts[0])
r = self.rpc.do(o)
self.assertEqual(int(r, 16), 0)
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
c = TokenUniqueSymbolIndex(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
(tx_hash_hex, o) = c.register(self.address, self.accounts[0], self.foo_token_address)
self.rpc.do(o)
c = AccountsIndex(self.chain_spec)
o = c.have(self.address, self.foo_token_address, sender_address=self.accounts[0])
r = self.rpc.do(o)
self.assertEqual(int(r, 16), 1)
if __name__ == '__main__':

View File

@ -85,6 +85,12 @@ contract TokenUniqueSymbolIndex {
return register(_token);
}
// Implements AccountsIndex
function time(address _token) public pure returns(uint256) {
_token;
return 0;
}
// Implements AccountsIndexMutable
function remove(address _token) external returns (bool) {
uint256 i;
@ -98,11 +104,12 @@ contract TokenUniqueSymbolIndex {
if (i < l) {
tokens[i] = tokens[l];
identifierList[i] = identifierList[l];
}
}
registry[tokenIndex[tokens[i]]] = i;
tokens.pop();
identifierList.pop();
registry[tokenIndex[_token]] = 0;
tokenIndex[_token] = bytes32(0);
emit AddressRemoved(_token);
return true;
@ -169,6 +176,11 @@ contract TokenUniqueSymbolIndex {
return identifierList.length - 1;
}
// Implements AccountsIndex
function have(address _token) public view returns(bool) {
return tokenIndex[_token] != bytes32(0x0);
}
// Implements EIP165
function supportsInterface(bytes4 _sum) public pure returns (bool) {
if (_sum == 0xeffbf671) { // Registry