springboot使用web3进行代币交换(uniswap)

5 篇文章 0 订阅
2 篇文章 0 订阅
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.StaticArray;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.EthGasPrice;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.http.HttpService;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

import io.renren.common.utils.R;
import net.sf.json.JSONObject;

@Service
public class Uniswap {
	private static final Logger log = LoggerFactory.getLogger(Uniswap.class);

	@Autowired
	private EthGas ethGas;

	@Autowired
	private EthAccount ethAccount;
	
	/**
	 * 
	 * @param gasLimit  gaslimit
	 * @param gasPrice   gas费用
	 * @param host       链路
	 * @param privateKey   自己的私钥
	 * @param v            要兑换的对应代币的
	 * @param contractAddress    如用USDT兑换BTC,则此值是BTC的合约地址
	 * @param amountOutMin      兑换代币的最小的个数
	 * @param sendTokenContractAddress   如用USDT兑换BTC,则此值是USDT的合约地址
	 * @param approveAddress	approve合约地址,设置此值可以合约内直接确认,无需调钱包插件确认
	 * @return
	 */
	public R sendContract(BigInteger gasLimit,BigInteger gasPrice,String host, String privateKey, BigDecimal v, String contractAddress, BigInteger amountOutMin,
			String sendTokenContractAddress,String approveAddress) {
		
		Web3j web3j = Web3j.build(new HttpService(host));
		try {
			Credentials credentials = Credentials.create(privateKey);
			String fromAddress = credentials.getAddress();
			//获取交易次数
			EthGetTransactionCount ethGetTransactionCount = ethAccount.getTradeCount(web3j, privateKey);
			//错误返回
			if (ethGetTransactionCount.hasError()) {
				return R.error(ethGetTransactionCount.getError().getMessage());
			}
			BigInteger nonce = ethGetTransactionCount.getTransactionCount();
			//合约函数参数
			List<Address> addList = new ArrayList<Address>();
			addList.add(new Address(sendTokenContractAddress));
			addList.add(new Address(approveAddress));
			StaticArray<Address> address = new StaticArray<Address>(Address.class, addList) {
			};
			// BigInteger amountOutMin = Numeric.toBigInt("0x8d5ff4d17003f1000");
			if(gasPrice.compareTo(BigInteger.valueOf(0)) != 1) { //没有输入gas时查询当前链路的gas
				EthGasPrice ethGasPrice = ethGas.getGasPrice(web3j);
				if (ethGasPrice.hasError()) {
					return R.error(ethGasPrice.getError().getMessage());
				}
				gasPrice = ethGasPrice.getGasPrice();
			}
			//创建inputdata
			String data = createSwapMethod(amountOutMin, address, addList.size(), new Address(fromAddress),
					new Uint256(System.currentTimeMillis() / 1000 + 300));
//			EthEstimateGas ethEstimateGas = ethGas.getEthEstimateGas(web3j, fromAddress, contractAddress, data);
//			if (ethEstimateGas.hasError()) {
//				return R.error(ethEstimateGas.getError().getMessage());
//			}
//			BigInteger gasLimit = BigInteger.valueOf(910000);
			
			BigInteger value = Convert.toWei(String.valueOf(v.toString()), Convert.Unit.ETHER).toBigInteger();
			RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, contractAddress,
					value, data);
			byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
			String hexValue = Numeric.toHexString(signedMessage);
			log.info("hexValue:{}", hexValue);
			//发送交易
			EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get();
			if (ethSendTransaction.hasError()) {
				return R.error(ethSendTransaction.getError().getMessage());
			}
			log.info("transactionHash:{}", JSONObject.fromObject(ethSendTransaction));
			String transactionHash = ethSendTransaction.getTransactionHash();
			log.info("transactionHash:{}", transactionHash);
			EthGetTransactionReceipt ethGetTransactionReceipt = web3j.ethGetTransactionReceipt(transactionHash)
					.sendAsync().get();
			log.info("EthGetTransactionReceipt:{}", JSONObject.fromObject(ethGetTransactionReceipt));
			if (ethGetTransactionReceipt.hasError()) {
				return R.error(ethGetTransactionReceipt.getError().getMessage());
			}
			return R.ok(transactionHash);
		} catch (Exception e) {
			// TODO: handle exception
			web3j.shutdown();
			return R.error(e.getMessage());
		}finally {
			web3j.shutdown();
		}

	}

	@SuppressWarnings("rawtypes")
	public static String createSwapMethod(BigInteger amountOutMin, StaticArray<Address> addressArray, int size,
			Address to, Uint256 deadline) {

		List<Type> parametersList = new ArrayList<Type>();
		parametersList.add(new Uint256(amountOutMin));
		parametersList.add(new Uint256(128));
		parametersList.add(to);
		parametersList.add(deadline);
		parametersList.add(new Uint256(BigInteger.valueOf(size)));
		parametersList.add(addressArray);
		List<TypeReference<?>> outList = new ArrayList<>();
		Function function = new Function("swapExactETHForTokens", parametersList, outList);
		String encodedFunction = FunctionEncoder.encode(function);
		System.out.println(encodedFunction);
		//函数编码不正确,先替换
		return encodedFunction.replace("0x8fd067c2", "0x7ff36ab5");
	}

}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值