erc721.py (6632B)
1 # external imports 2 from chainlib.eth.tx import ( 3 TxFormat, 4 TxFactory, 5 ) 6 from chainlib.eth.contract import ( 7 ABIContractEncoder, 8 ABIContractType, 9 abi_decode_single, 10 ) 11 from chainlib.jsonrpc import JSONRPCRequest 12 from chainlib.eth.constant import ZERO_ADDRESS 13 from hexathon import ( 14 add_0x, 15 ) 16 from eth_erc20 import ERC20 17 from eth_owned import ERC173 18 19 20 class ERC721(ERC20, ERC173): 21 22 def transfer(self, contract_address, sender_address, recipient_address, value, tx_format=TxFormat.JSONRPC): 23 raise NotImplementedError('EIP721 does not implement ERC20.transfer') 24 25 26 def set_approve_for_all(self, contract_address, sender_address, operator_address, flag, tx_format=TxFormat.JSONRPC): 27 enc = ABIContractEncoder() 28 enc.method('setApprovalForAll') 29 enc.typ(ABIContractType.ADDRESS) 30 enc.typ(ABIContractType.BOOLEAN) 31 enc.address(operator_address) 32 enc.uint256(int(flag)) 33 data = enc.get() 34 tx = self.template(sender_address, contract_address, use_nonce=True) 35 tx = self.set_code(tx, data) 36 tx = self.finalize(tx, tx_format) 37 return tx 38 39 40 def set_operator(self, contract_address, sender_address, operator_address, tx_format=TxFormat.JSONRPC): 41 return self.set_approve_for_all(contract_address, sender_address, operator_address, True, tx_format=tx_format) 42 43 44 def remove_operator(self, contract_address, sender_address, operator_address, tx_format=TxFormat.JSONRPC): 45 return self.set_approve_for_all(contract_address, sender_address, operator_address, False, tx_format=tx_format) 46 47 48 def token_by_index(self, contract_address, idx, sender_address=ZERO_ADDRESS, id_generator=None): 49 j = JSONRPCRequest(id_generator) 50 o = j.template() 51 o['method'] = 'eth_call' 52 enc = ABIContractEncoder() 53 enc.method('tokenByIndex') 54 enc.typ(ABIContractType.UINT256) 55 enc.uint256(idx) 56 data = add_0x(enc.get()) 57 tx = self.template(sender_address, contract_address) 58 tx = self.set_code(tx, data) 59 o['params'].append(self.normalize(tx)) 60 o['params'].append('latest') 61 o = j.finalize(o) 62 return o 63 64 65 def owner_of(self, contract_address, token_id, sender_address=ZERO_ADDRESS, id_generator=None): 66 j = JSONRPCRequest(id_generator) 67 o = j.template() 68 o['method'] = 'eth_call' 69 enc = ABIContractEncoder() 70 enc.method('ownerOf') 71 enc.typ(ABIContractType.UINT256) 72 enc.uint256(token_id) 73 data = add_0x(enc.get()) 74 tx = self.template(sender_address, contract_address) 75 tx = self.set_code(tx, data) 76 o['params'].append(self.normalize(tx)) 77 o['params'].append('latest') 78 o = j.finalize(o) 79 return o 80 81 82 def is_approved_for_all(self, contract_address, holder_address, operator_address, sender_address=ZERO_ADDRESS, id_generator=None): 83 j = JSONRPCRequest(id_generator) 84 o = j.template() 85 o['method'] = 'eth_call' 86 enc = ABIContractEncoder() 87 enc.method('isApprovedForAll') 88 enc.typ(ABIContractType.ADDRESS) 89 enc.typ(ABIContractType.ADDRESS) 90 enc.address(holder_address) 91 enc.address(operator_address) 92 data = add_0x(enc.get()) 93 tx = self.template(sender_address, contract_address) 94 tx = self.set_code(tx, data) 95 o['params'].append(self.normalize(tx)) 96 o['params'].append('latest') 97 o = j.finalize(o) 98 return o 99 100 101 def is_operator(self, contract_address, token_id, operator_address, sender_address=ZERO_ADDRESS): 102 return self.is_approved_for_all(contract_address, token_id, operator_address, sender_address=sender_address) 103 104 105 def get_approved(self, contract_address, token_id, sender_address=ZERO_ADDRESS, id_generator=None): 106 j = JSONRPCRequest(id_generator) 107 o = j.template() 108 o['method'] = 'eth_call' 109 enc = ABIContractEncoder() 110 enc.method('getApproved') 111 enc.typ(ABIContractType.UINT256) 112 enc.uint256(token_id) 113 data = add_0x(enc.get()) 114 tx = self.template(sender_address, contract_address) 115 tx = self.set_code(tx, data) 116 o['params'].append(self.normalize(tx)) 117 o['params'].append('latest') 118 o = j.finalize(o) 119 return o 120 121 122 123 def token_of_owner_by_index(self, contract_address, holder_address, idx, sender_address=ZERO_ADDRESS, id_generator=None): 124 j = JSONRPCRequest(id_generator) 125 o = j.template() 126 o['method'] = 'eth_call' 127 enc = ABIContractEncoder() 128 enc.method('tokenOfOwnerByIndex') 129 enc.typ(ABIContractType.ADDRESS) 130 enc.typ(ABIContractType.UINT256) 131 enc.address(holder_address) 132 enc.uint256(idx) 133 data = add_0x(enc.get()) 134 tx = self.template(sender_address, contract_address) 135 tx = self.set_code(tx, data) 136 o['params'].append(self.normalize(tx)) 137 o['params'].append('latest') 138 o = j.finalize(o) 139 return o 140 141 142 def token_uri(self, contract_address, token_id, sender_address=ZERO_ADDRESS, id_generator=None): 143 j = JSONRPCRequest(id_generator) 144 o = j.template() 145 o['method'] = 'eth_call' 146 enc = ABIContractEncoder() 147 enc.method('tokenURI') 148 enc.typ(ABIContractType.UINT256) 149 enc.uint256(token_id) 150 data = add_0x(enc.get()) 151 tx = self.template(sender_address, contract_address) 152 tx = self.set_code(tx, data) 153 o['params'].append(self.normalize(tx)) 154 o['params'].append('latest') 155 o = j.finalize(o) 156 return o 157 158 159 @classmethod 160 def parse_owner_of(self, v): 161 return abi_decode_single(ABIContractType.ADDRESS, v) 162 163 164 @classmethod 165 def parse_token_by_index(self, v): 166 return abi_decode_single(ABIContractType.UINT256, v) 167 168 169 @classmethod 170 def parse_token_of_owner_by_index(self, v): 171 return abi_decode_single(ABIContractType.UINT256, v) 172 173 174 @classmethod 175 def parse_total_supply(self, v): 176 return abi_decode_single(ABIContractType.UINT256, v) 177 178 179 @classmethod 180 def parse_is_approved_for_all(self, v): 181 return abi_decode_single(ABIContractType.BOOLEAN, v) 182 183 184 @classmethod 185 def parse_is_operator(self, v): 186 return self.parse_is_approved_for_all(v) 187 188 189 @classmethod 190 def parse_get_approved(self, v): 191 return abi_decode_single(ABIContractType.ADDRESS, v) 192 193 194 @classmethod 195 def parse_token_uri(self, v): 196 return abi_decode_single(ABIContractType.STRING, v)