Browse Source

proto.eth.contract: new `create_token_data()` method

The MMGen Project 1 week ago
parent
commit
62475d39e9
3 changed files with 24 additions and 51 deletions
  1. 20 46
      mmgen/proto/eth/contract.py
  2. 1 1
      mmgen/proto/eth/tx/new.py
  3. 3 4
      mmgen/proto/eth/tx/unsigned.py

+ 20 - 46
mmgen/proto/eth/contract.py

@@ -58,6 +58,15 @@ class Contract:
 		else:
 			return ret
 
+	def make_tx_in(self, *, gas, gasPrice, nonce, data):
+		return {
+			'to':       bytes.fromhex(self.addr),
+			'startgas': gas.toWei(),
+			'gasprice': gasPrice.toWei(),
+			'value':    0,
+			'nonce':    nonce,
+			'data':     bytes.fromhex(data)}
+
 	async def txsign(self, tx_in, key, from_addr, *, chain_id=None):
 
 		from .pyethereum.transactions import Transaction
@@ -129,38 +138,6 @@ class Token(Contract):
 			'decimals:',      self.decimals,
 			'total supply:',  await self.get_total_supply())
 
-	def create_data(
-			self,
-			to_addr,
-			amt,
-			*,
-			method_sig = 'transfer(address,uint256)'):
-		from_arg = ''
-		to_arg = to_addr.rjust(64, '0')
-		amt_arg = '{:064x}'.format(int(amt / self.base_unit))
-		return self.create_method_id(method_sig) + from_arg + to_arg + amt_arg
-
-	def make_tx_in(
-			self,
-			*,
-			to_addr,
-			amt,
-			gas,
-			gasPrice,
-			nonce,
-			method_sig = 'transfer(address,uint256)'):
-		data = self.create_data(
-				to_addr,
-				amt,
-				method_sig = method_sig)
-		return {
-			'to':       bytes.fromhex(self.addr),
-			'startgas': gas.toWei(),
-			'gasprice': gasPrice.toWei(),
-			'value':    0,
-			'nonce':    nonce,
-			'data':     bytes.fromhex(data)}
-
 	def transferdata2sendaddr(self, data): # online
 		return CoinAddr(self.proto, parse_abi(data)[1][-40:])
 
@@ -169,24 +146,21 @@ class Token(Contract):
 			int(parse_abi(data)[-1], 16) * self.base_unit,
 			from_decimal = True)
 
+	def create_token_data(self, to_addr, amt, *, op):
+		assert op in ('transfer', 'approve'), f'{op}: invalid operation (not ‘transfer’ or ‘approve’)'
+		return (
+			self.create_method_id(f'{op}(address,uint256)')
+			+ to_addr.rjust(64, '0')
+			+ '{:064x}'.format(int(amt / self.base_unit)))
+
 	# used for testing only:
-	async def transfer(
-			self,
-			*,
-			from_addr,
-			to_addr,
-			amt,
-			key,
-			gas,
-			gasPrice,
-			method_sig = 'transfer(address,uint256)'):
+	async def transfer(self, *, from_addr, to_addr, amt, key, gas, gasPrice):
+		nonce = await self.rpc.call('eth_getTransactionCount', '0x'+from_addr, 'pending')
 		tx_in = self.make_tx_in(
-			to_addr  = to_addr,
-			amt      = amt,
 			gas      = gas,
 			gasPrice = gasPrice,
-			nonce    = int(await self.rpc.call('eth_getTransactionCount', '0x'+from_addr, 'pending'), 16),
-			method_sig = method_sig)
+			nonce    = int(nonce, 16),
+			data     = self.create_token_data(to_addr, amt, op='transfer'))
 		res = await self.txsign(tx_in, key, from_addr)
 		return await self.txsend(res.txhex)
 

+ 1 - 1
mmgen/proto/eth/tx/new.py

@@ -216,7 +216,7 @@ class TokenNew(TokenBase, New):
 		o['token_addr'] = t.addr
 		o['decimals'] = t.decimals
 		o['token_to'] = o['to']
-		o['data'] = t.create_data(o['token_to'], o['amt'])
+		o['data'] = t.create_token_data(o['token_to'], o['amt'], op='transfer')
 
 	def update_change_output(self, funds_left):
 		if self.outputs[0].is_chg:

+ 3 - 4
mmgen/proto/eth/tx/unsigned.py

@@ -108,17 +108,16 @@ class TokenUnsigned(TokenCompleted, Unsigned):
 		o['token_addr'] = TokenAddr(self.proto, d['token_addr'])
 		o['decimals'] = Int(d['decimals'])
 		t = Token(self.cfg, self.proto, o['token_addr'], o['decimals'])
-		o['data'] = t.create_data(o['to'], o['amt'])
+		o['data'] = t.create_token_data(o['to'], o['amt'], op='transfer')
 		o['token_to'] = t.transferdata2sendaddr(o['data'])
 
 	async def do_sign(self, o, wif):
 		t = Token(self.cfg, self.proto, o['token_addr'], o['decimals'])
 		tx_in = t.make_tx_in(
-			to_addr  = o['to'],
-			amt      = o['amt'],
 			gas      = self.gas,
 			gasPrice = o['gasPrice'],
-			nonce    = o['nonce'])
+			nonce    = o['nonce'],
+			data     = t.create_token_data(o['to'], o['amt'], op='transfer'))
 		res = await t.txsign(tx_in, wif, o['from'], chain_id=o['chainId'])
 		self.serialized = res.txhex
 		self.coin_txid = res.txid