一、安装pyuniswap
pip install pyuniswap
二、pyunsiwap使用方法
以购买BAS代币进行举例说明:
from pyuniswap import pyuniswap
#所需交易的bas代币的合约地址
bas_address = '0xa7ed29b253d8b4e3109ce07c80fc570f81b63696'
#在infura上申请一个节点地址当作provider
my_provider = 'https://mainnet.infura.io/v3/'
#实例化一个代表bas代币的对象
bas = Token(prq_address, my_provider)
#连接钱包
bas.connect_wallet('waller_address', 'private_key')
#检查是否连接成功
bas.is_connected()
#钱包中该代币的余额
balance=bas.balance()
#钱包中该代币的价值(默认以eth作为计量单位)
bas.price(balance)
#1个eth能换多少该代币
bas.received_amount_by_swap(int(1e18)))
#买1eth的该代币
bas.buy(int(1e18), slippage=0.05)
三、pyuniswap源码解析
面向对象的风格,Token类,实例化对象后可以调用其中的成员方法,以下是主要的几个方法:
1.price()
def price(self, amount=int(1e18), swap_token_address=ETH_ADDRESS):
swap_token_address = Web3.toChecksumAddress(swap_token_address)
return self.router.functions.getAmountsOut(amount, [self.address, swap_token_address]).call()[-1]
传入的参数分别是想要交易的数量与想要获得的代币地址(默认是eth地址)。
可以理解为返回指定数量的代币价值。
2.received_amount_by_swap()
def received_amount_by_swap(self, input_token_amount=int(1e18), input_token_address=ETH_ADDRESS):
input_token_address = Web3.toChecksumAddress(input_token_address)
return self.router.functions.getAmountsOut(input_token_amount, [input_token_address, self.address]).call()[-1]
可以理解为用指定数量的其他代币换取该代币,返回能换得该代币的数量。
3.buy()
def buy(self, consumed_token_amount, consumed_token_address=ETH_ADDRESS, slippage=0.01, timeout=900, speed=1):
gas_price = int(self.web3.eth.gasPrice * speed)
consumed_token_address = Web3.toChecksumAddress(consumed_token_address)
received_amount = self.received_amount_by_swap(consumed_token_amount, consumed_token_address)
min_out = int(received_amount * (1 - slippage))
if consumed_token_address == self.ETH_ADDRESS:
func = self.router.functions.swapExactETHForTokens(min_out, [consumed_token_address, self.address],
self.wallet_address, int(time.time() + timeout))
params = self.create_transaction_params(value=consumed_token_amount, gas_price=gas_price)
else:
if not self.is_approved(consumed_token_address, consumed_token_amount):
self.approve(consumed_token_address, gas_price=gas_price, timeout=timeout)
func = self.router.functions.swapExactTokensForTokens(consumed_token_amount, min_out,
[consumed_token_address, self.address],
self.wallet_address, int(time.time() + timeout))
params = self.create_transaction_params(gas_price=gas_price)
return self.send_transaction(func, params)
一共有5个参数:
consumed_token_address:设置所支付的代币的erc20合约地址。
consumed_token_amount:设置所支付的代币数量。
slippage:设置所能容忍的滑点,默认为百分之一。
timeout:设置该笔交易的超时时间。
speed:设置该笔交易的区块确认速度,通过平均的gas_price乘以speed设置该笔交易的gas_price,所以speed的值越大,gas_price也越大,使得该笔交易的确认速度也越快。
四、挂限价单的方法
这里以挂限价卖单作为演示:
from pyuniswap import pyuniswap
bas_address = '0xa7ed29b253d8b4e3109ce07c80fc570f81b63696'
my_provider = 'https://mainnet.infura.io/v3/'
bas = pyuniswap.Token(base_address, my_provider)
bas.connect_wallet('', '')
balance = base.balance()
my_token=bas
price_start=my_token.price()
target_price=2*price_start
while True:
price_now=my_token.price()
if price_now>=target_price:
my_token.sell(my_token.balance(),slippage=0.1,speed=1.5)
break
time.sleep(1)
运行上述代码后,当价格翻倍时,会卖出所有钱包里所有的BAS代币。
五、rebase代币的处理
此外,有些代币有rebase功能,在rebase之后即使价格没变,但拥有的数量可能会发生变化。针对这一情况,可以使用下面的这段代码使得当所拥有的代币的总价值翻倍时,在uniswap上执行卖出交易。
current_value=my_token.price(balance)
target_value=2*current_value
while True:
value_now=my_token.price(my_token.balance())
if value_now>=target_value:
my_token.sell(my_token.balance(),slippage=0.1,speed=1.5)
break
time.sleep(1)