commit 8c49343202050d2411d912760d778dcdbf530aa9
parent d5174a7acaad0a395bbbd48b4e8ab29176eed2ee
Author: nolash <dev@holbrook.no>
Date: Sat, 8 May 2021 07:34:58 +0200
Implement operator
Diffstat:
2 files changed, 102 insertions(+), 2 deletions(-)
diff --git a/python/eth_devbadge/token.py b/python/eth_devbadge/token.py
@@ -95,6 +95,28 @@ class BadgeToken(TxFactory):
return tx
+ def set_approve_for_all(self, contract_address, sender_address, operator_address, flag, tx_format=TxFormat.JSONRPC):
+ enc = ABIContractEncoder()
+ enc.method('setApprovalForAll')
+ enc.typ(ABIContractType.ADDRESS)
+ enc.typ(ABIContractType.BOOLEAN)
+ enc.address(operator_address)
+ enc.uint256(int(flag))
+ 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 set_operator(self, contract_address, sender_address, operator_address, tx_format=TxFormat.JSONRPC):
+ return self.set_approve_for_all(contract_address, sender_address, operator_address, True, tx_format=tx_format)
+
+
+ def remove_operator(self, contract_address, sender_address, operator_address, tx_format=TxFormat.JSONRPC):
+ return self.set_approve_for_all(contract_address, sender_address, operator_address, False, tx_format=tx_format)
+
+
def token_by_index(self, contract_address, idx, sender_address=ZERO_ADDRESS):
o = jsonrpc_template()
o['method'] = 'eth_call'
@@ -125,6 +147,27 @@ class BadgeToken(TxFactory):
return o
+ def is_approved_for_all(self, contract_address, holder_address, operator_address, sender_address=ZERO_ADDRESS):
+ o = jsonrpc_template()
+ o['method'] = 'eth_call'
+ enc = ABIContractEncoder()
+ enc.method('isApprovedForAll')
+ enc.typ(ABIContractType.ADDRESS)
+ enc.typ(ABIContractType.ADDRESS)
+ enc.address(holder_address)
+ enc.address(operator_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 is_operator(self, contract_address, token_id, operator_address, sender_address=ZERO_ADDRESS):
+ return self.is_approved_for_all(contract_address, token_id, operator_address, sender_address=sender_address)
+
+
def token_of_owner_by_index(self, contract_address, holder_address, idx, sender_address=ZERO_ADDRESS):
o = jsonrpc_template()
o['method'] = 'eth_call'
@@ -175,3 +218,11 @@ class BadgeToken(TxFactory):
return abi_decode_single(ABIContractType.UINT256, v)
+ @classmethod
+ def parse_is_approved_for_all(self, v):
+ return abi_decode_single(ABIContractType.BOOLEAN, v)
+
+
+ @classmethod
+ def parse_is_operator(self, v):
+ return self.parse_is_approved_for_all(v)
diff --git a/python/tests/test_app.py b/python/tests/test_app.py
@@ -94,6 +94,55 @@ class Test(EthTesterCase):
r = self.rpc.do(o)
self.assertEqual(token_bytes.hex(), strip_0x(r))
+
+ def test_operator(self):
+ token_bytes = b'\xee' * 32
+ token_id = int.from_bytes(token_bytes, byteorder='big')
+ c = self._mint(self.accounts[1], token_id)
+
+ nonce_oracle = RPCNonceOracle(self.accounts[1], self.rpc)
+ c = BadgeToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ (tx_hash_hex, o) = c.set_operator(self.address, self.accounts[1], self.accounts[2])
+ r = self.rpc.do(o)
+
+ o = receipt(tx_hash_hex)
+ r = self.conn.do(o)
+ self.assertEqual(r['status'], 1)
+
+ o = c.is_operator(self.address, self.accounts[1], self.accounts[2], sender_address=self.accounts[0])
+ r = self.rpc.do(o)
+ isop = c.parse_is_operator(r)
+ self.assertTrue(isop)
+
+ (tx_hash_hex, o) = c.remove_operator(self.address, self.accounts[1], self.accounts[2])
+ r = self.rpc.do(o)
+
+ o = receipt(tx_hash_hex)
+ r = self.conn.do(o)
+ self.assertEqual(r['status'], 1)
+
+ o = c.is_operator(self.address, self.accounts[1], self.accounts[2], sender_address=self.accounts[0])
+ r = self.rpc.do(o)
+ isop = c.parse_is_operator(r)
+ self.assertFalse(isop)
+
+ (tx_hash_hex, o) = c.set_operator(self.address, self.accounts[1], self.accounts[2])
+ r = self.rpc.do(o)
+
+ nonce_oracle = RPCNonceOracle(self.accounts[2], self.rpc)
+ c = BadgeToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ (tx_hash_hex, o) = c.transfer_from(self.address, self.accounts[2], self.accounts[1], self.accounts[3], token_id)
+ r = self.rpc.do(o)
+
+ o = receipt(tx_hash_hex)
+ r = self.conn.do(o)
+ self.assertEqual(r['status'], 1)
+
+ o = c.owner_of(self.address, token_id, sender_address=self.accounts[0])
+ r = self.rpc.do(o)
+ owner_address = c.parse_owner_of(r)
+ self.assertEqual(owner_address, self.accounts[3])
+
def test_transfer(self):
token_bytes = b'\xee' * 32
@@ -113,10 +162,10 @@ class Test(EthTesterCase):
with self.assertRaises(JSONRPCException):
r = self.rpc.do(o)
-
o = c.token_of_owner_by_index(self.address, self.accounts[2], 0, sender_address=self.accounts[0])
r = self.rpc.do(o)
self.assertEqual(token_bytes.hex(), strip_0x(r))
-
+
+
if __name__ == '__main__':
unittest.main()