以太坊区块链浏览器有提供官方api 已经满足了基本开发需求 优点: 可以不用搭建节点,节省内存,无须担心节点挂掉影响业务 缺点:官方限制请求接口频率最高为 每秒为5次/ip地址,无法像节点一样监听,需要跑定时任务去查询新的交易 之前写过了搭节点开发的教程 细节和概念不想再说一遍了 直接上代码 交易功能和搭节点有点差别 这里是 构建交易→离线签名→编码→用api接口广播 maven和jar包去 之前的博客 的3(web3j引入)看,一毛一样 不想再写一次 有不懂的也可以看一下 接口 实现类 http工具类 常量类readme
api连接直接上代码
package com.lim.service; import com.alibaba.fastjson.JSONObject; import java.math.BigInteger; public interface IAccountService { /** * 离线创建账户 * @param pwd * @return */ JSONObject createAccount(String pwd); /** * 获取当前gasPrice * @return */ JSONObject getGasPrice() throws Exception; /** * 检查交易状态 0-正常 1-交易错误 * @param hash * @return * @throws Exception */ String checkTran(String hash) throws Exception; /** * 检查交易pending状态 0-失败 1-已完成 null/umpty-pending中 * @return * @throws Exception */ String checkTranPending(String hash) throws Exception; /** * 获取地址的交易数量 * @param address * @return * @throws Exception */ BigInteger getTranNum(String address) throws Exception; /** * 获取账户eth余额 * @param address * @return */ String getEthBalance(String address) throws Exception; /** * 获取账户usdt余额 * @param address * @return */ String getUsdtBalance(String address) throws Exception; /** * eth交易 * @param from * @param to * @param privateKey * @param num * @param gasPrice * @param nonce * @return * @throws Exception */ JSONObject tranEth(String from, String to, String privateKey, String num, String gasPrice, String nonce) throws Exception; /** * usdt交易 * @param from * @param to * @param privateKey * @param num * @param gasPrice * @param gaslimit * @param nonce * @return */ JSONObject tranUsdt(String from, String to, String privateKey, String num, String gasPrice, String gaslimit, String nonce)throws Exception; }
package com.lim.service.impl; import com.alibaba.fastjson.JSONObject; import com.lim.eth.EthConstant; import com.lim.redis.IRedisService; import com.lim.service.IAccountService; import com.lim.util.HttpUtils; import io.github.novacrypto.bip39.MnemonicGenerator; import io.github.novacrypto.bip39.SeedCalculator; import io.github.novacrypto.bip39.Words; import io.github.novacrypto.bip39.wordlists.English; import io.github.novacrypto.hashing.Sha256; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpResponse; import org.apache.http.util.EntityUtils; import org.springframework.stereotype.Service; import org.web3j.abi.FunctionEncoder; import org.web3j.abi.datatypes.Address; import org.web3j.abi.datatypes.Function; import org.web3j.abi.datatypes.generated.Uint256; import org.web3j.crypto.*; import org.web3j.utils.Convert; import org.web3j.utils.Numeric; import javax.annotation.Resource; import java.math.BigInteger; import java.security.SecureRandom; import java.util.*; @Slf4j @Service public class EAccountServiceImpl implements IAccountService { @Resource private IRedisService redisService; private final Map<String, String> headers = new HashMap<>(); private final Map<String, String> querys = headers; @Override public JSONObject createAccount(String pwd) { StringBuilder sb = new StringBuilder(); byte[] entropy = new byte[Words.TWELVE.byteLength()]; new SecureRandom().nextBytes(entropy); new MnemonicGenerator(English.INSTANCE).createMnemonic(entropy, sb::append); String mnemonic = sb.toString(); List mnemonicList = Arrays.asList(mnemonic.split(" ")); byte[] seed = new SeedCalculator().withWordsFromWordList(English.INSTANCE).calculateSeed(mnemonicList, pwd); ECKeyPair ecKeyPair = ECKeyPair.create(Sha256.sha256(seed)); String privateKey = ecKeyPair.getPrivateKey().toString(16); String publicKey = ecKeyPair.getPublicKey().toString(16); String address = "0x" + Keys.getAddress(publicKey); JSONObject json = new JSONObject(); json.put("privateKey", privateKey); json.put("publicKey", publicKey); json.put("address", address); return json; } @Override public JSONObject getGasPrice() throws Exception { StringBuffer path = new StringBuffer("/api?module=gastracker&action=gasoracle&apikey=").append(EthConstant.ETHERSCAN_API_KEY); HttpResponse response = HttpUtils.doGet("https://api.etherscan.io", path.toString(), "GET", headers, querys); String res = EntityUtils.toString(response.getEntity()); JSONObject json = JSONObject.parseObject(res); String status = json.getString("status"); if(!status.equals("1")){ throw new Exception(json.getString("message")); } JSONObject resJson = json.getJSONObject("result"); return resJson; } @Override public String checkTran(String hash) throws Exception { StringBuffer path = new StringBuffer("/api?module=transaction&action=getstatus&txhash=").append(hash) .append("&apikey=").append(EthConstant.ETHERSCAN_API_KEY); HttpResponse response = HttpUtils.doGet("https://api.etherscan.io", path.toString(), "GET", headers, querys); String res = EntityUtils.toString(response.getEntity()); JSONObject json = JSONObject.parseObject(res); String status = json.getString("status"); if(!status.equals("1")){ throw new Exception(json.getString("message")); } JSONObject resJson = json.getJSONObject("result"); return resJson.getString("isError"); } @Override public String checkTranPending(String hash) throws Exception { StringBuffer path = new StringBuffer("/api?module=transaction&action=gettxreceiptstatus&txhash=").append(hash) .append("&apikey=").append(EthConstant.ETHERSCAN_API_KEY); HttpResponse response = HttpUtils.doGet("https://api.etherscan.io", path.toString(), "GET", headers, querys); String res = EntityUtils.toString(response.getEntity()); JSONObject json = JSONObject.parseObject(res); String status = json.getString("status"); if(!status.equals("1")){ throw new Exception(json.getString("message")); } JSONObject resJson = json.getJSONObject("result"); return resJson.getString("status"); } @Override public BigInteger getTranNum(String address) throws Exception { StringBuffer path = new StringBuffer("/api?module=proxy&action=eth_getTransactionCount&address=").append(address) .append("&tag=latest&apikey=").append(EthConstant.ETHERSCAN_API_KEY); HttpResponse response = HttpUtils.doGet("https://api.etherscan.io", path.toString(), "GET", headers, querys); String res = EntityUtils.toString(response.getEntity()); JSONObject json = JSONObject.parseObject(res); String result = json.getString("result"); return new BigInteger(result.substring(2), 16); } @Override public String getEthBalance(String address) throws Exception { StringBuffer path = new StringBuffer("/api?module=account&action=balance&address=").append(address) .append("&tag=latest&apikey=").append(EthConstant.ETHERSCAN_API_KEY); HttpResponse response = HttpUtils.doGet("https://api.etherscan.io", path.toString(), "GET", headers, querys); String res = EntityUtils.toString(response.getEntity()); JSONObject json = JSONObject.parseObject(res); String status = json.getString("status"); if(!status.equals("1")){ throw new Exception(json.getString("message")); } String num = json.getString("result"); return Convert.fromWei(num, Convert.Unit.ETHER).toString(); } @Override public String getUsdtBalance(String address) throws Exception { StringBuffer path = new StringBuffer("/api?module=account&action=tokenbalance&contractaddress=").append(EthConstant.CONTRACTA_DDRESS) .append("&address=").append(address).append("&tag=latest&apikey=").append(EthConstant.ETHERSCAN_API_KEY); HttpResponse response = HttpUtils.doGet("https://api.etherscan.io", path.toString(), "GET", headers, querys); String res = EntityUtils.toString(response.getEntity()); JSONObject json = JSONObject.parseObject(res); String status = json.getString("status"); if(!status.equals("1")){ throw new Exception(json.getString("message")); } String num = json.getString("result"); return Convert.fromWei(num, Convert.Unit.MWEI).toString(); } @Override public JSONObject tranEth(String from, String to, String privateKey, String num, String gasPrice, String nonce) throws Exception { String pending = redisService.getString(EthConstant.ADDRESS_TRAN_PENDING_KEY + from); log.info("pending: " + pending); List<String> list = new ArrayList<>(); if(pending != null && pending.length() > 50 ){ //有在pending中的交易 要加nonce list = new ArrayList<>(Arrays.asList(pending.split(","))); for(int i = 0; i < list.size(); i++){ String hash = list.get(i); String pendingStatus = this.checkTranPending(hash); if(StringUtils.isNotBlank(pendingStatus)){ list.remove(i); } } } log.info("list size: " + list.size()); BigInteger gasPriceNum = null; if(StringUtils.isNotBlank(gasPrice) && new BigInteger(gasPrice).compareTo(new BigInteger("1")) >= 0){ gasPriceNum = Convert.toWei(gasPrice, Convert.Unit.GWEI).toBigInteger(); } else { gasPriceNum = Convert.toWei(getGasPrice().getString("ProposeGasPrice"), Convert.Unit.GWEI).toBigInteger(); } BigInteger nonceMum = null; if(StringUtils.isNotBlank(nonce) && new BigInteger(nonce).compareTo(new BigInteger("0")) >= 0 ){ nonceMum = new BigInteger(nonce); } else { nonceMum = this.getTranNum(from); nonceMum = nonceMum.add(new BigInteger(String.valueOf(list.size()))); } RawTransaction rawTransaction = RawTransaction.createEtherTransaction( nonceMum, gasPriceNum , new BigInteger("21000"), to,Convert.toWei(num, Convert.Unit.ETHER).toBigInteger()); Credentials credentials = Credentials.create(privateKey); byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); String hexValue = Numeric.toHexString(signedMessage); StringBuffer path = new StringBuffer("/api?module=proxy&action=eth_sendRawTransaction&hex=").append(hexValue) .append("&apikey=").append(EthConstant.ETHERSCAN_API_KEY); HttpResponse response = HttpUtils.doGet("https://api.etherscan.io", path.toString(), "GET", headers, querys); String res = EntityUtils.toString(response.getEntity()); JSONObject json = JSONObject.parseObject(res); log.info(json.toString()); String hash = json.getString("result"); if(StringUtils.isBlank(hash)){ throw new Exception(json.getJSONObject("error").getString("message")); } list.add(hash); StringBuffer sb = new StringBuffer(""); for(String str: list){ sb.append(str).append(","); } String val = sb.substring(0, sb.length() -1); redisService.setString(EthConstant.ADDRESS_TRAN_PENDING_KEY + from, val); JSONObject jsonObject = new JSONObject(); jsonObject.put("nonce", nonce); jsonObject.put("hash", hash); return jsonObject; } @Override public JSONObject tranUsdt(String from, String to, String privateKey, String num , String gasPrice, String gaslimit, String nonce) throws Exception { BigInteger tranNum = Convert.toWei(num, Convert.Unit.MWEI).toBigInteger(); Function function = new Function("transfer", Arrays.asList( new Address(to), new Uint256(tranNum) ), Collections.emptyList()); String encodeFunction = FunctionEncoder.encode(function); String pending = redisService.getString(EthConstant.ADDRESS_TRAN_PENDING_KEY + from); log.info("pending: " + pending); List<String> list = new ArrayList<>(); if(pending != null && pending.length() > 50 ){ //有在pending中的交易 要加nonce list = new ArrayList<>(Arrays.asList(pending.split(","))); for(int i = 0; i < list.size(); i++){ String hash = list.get(i); String pendingStatus = this.checkTranPending(hash); if(StringUtils.isNotBlank(pendingStatus)){ list.remove(i); } } } log.info("list size: " + list.size()); BigInteger gasPriceNum = null; if(StringUtils.isNotBlank(gasPrice) && new BigInteger(gasPrice).compareTo(new BigInteger("1")) >= 0){ gasPriceNum = Convert.toWei(gasPrice, Convert.Unit.GWEI).toBigInteger(); } else { gasPriceNum = Convert.toWei(getGasPrice().getString("ProposeGasPrice"), Convert.Unit.GWEI).toBigInteger(); } BigInteger gasLimitNum = new BigInteger("100000"); if(StringUtils.isNotBlank(gaslimit) && new BigInteger(gaslimit).compareTo(new BigInteger("21000")) >= 0){ gasLimitNum = new BigInteger(gaslimit); } BigInteger nonceMum = null; if(StringUtils.isNotBlank(nonce) && new BigInteger(nonce).compareTo(new BigInteger("0")) >= 0 ){ nonceMum = new BigInteger(nonce); } else { nonceMum = this.getTranNum(from); nonceMum = nonceMum.add(new BigInteger(String.valueOf(list.size()))); } RawTransaction rawTransaction = RawTransaction.createTransaction( nonceMum, gasPriceNum, gasLimitNum , EthConstant.CONTRACTA_DDRESS, encodeFunction); Credentials credentials = Credentials.create(privateKey); byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); String hexValue = Numeric.toHexString(signedMessage); StringBuffer path = new StringBuffer("/api?module=proxy&action=eth_sendRawTransaction&hex=").append(hexValue) .append("&apikey=").append(EthConstant.ETHERSCAN_API_KEY); HttpResponse response = HttpUtils.doGet("https://api.etherscan.io", path.toString(), "GET", headers, querys); String res = EntityUtils.toString(response.getEntity()); JSONObject json = JSONObject.parseObject(res); log.info(json.toString()); String hash = json.getString("result"); if(StringUtils.isBlank(hash)){ throw new Exception(json.getJSONObject("error").getString("message")); } list.add(hash); StringBuffer sb = new StringBuffer(""); for(String str: list){ sb.append(str).append(","); } String val = sb.substring(0, sb.length() -1); redisService.setString(EthConstant.ADDRESS_TRAN_PENDING_KEY + from, val); JSONObject jsonObject = new JSONObject(); jsonObject.put("nonce", nonceMum); jsonObject.put("hash", hash); return jsonObject; } }
package com.lim.util; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import java.util.Map; public class HttpUtils { public static HttpResponse doGet(String host, String path, String method, Map<String, String> headers, Map<String, String> querys) throws Exception { HttpClient httpClient = wrapClient(host); HttpGet request = new HttpGet(buildUrl(host, path, querys)); for (Map.Entry<String, String> e : headers.entrySet()) { request.addHeader(e.getKey(), e.getValue()); } return httpClient.execute(request); } public static HttpResponse doPost(String host, String path, String method, Map<String, String> headers, Map<String, String> querys, Map<String, String> bodys) throws Exception { HttpClient httpClient = wrapClient(host); HttpPost request = new HttpPost(buildUrl(host, path, querys)); for (Map.Entry<String, String> e : headers.entrySet()) { request.addHeader(e.getKey(), e.getValue()); } if (bodys != null) { List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>(); for (String key : bodys.keySet()) { nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key))); } UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8"); formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8"); request.setEntity(formEntity); } return httpClient.execute(request); } private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException { StringBuilder sbUrl = new StringBuilder(); sbUrl.append(host); if (!StringUtils.isBlank(path)) { sbUrl.append(path); } if (null != querys) { StringBuilder sbQuery = new StringBuilder(); for (Map.Entry<String, String> query : querys.entrySet()) { if (0 < sbQuery.length()) { sbQuery.append("&"); } if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) { sbQuery.append(query.getValue()); } if (!StringUtils.isBlank(query.getKey())) { sbQuery.append(query.getKey()); if (!StringUtils.isBlank(query.getValue())) { sbQuery.append("="); sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8")); } } } if (0 < sbQuery.length()) { sbUrl.append("?").append(sbQuery); } } return sbUrl.toString(); } private static HttpClient wrapClient(String host) { HttpClient httpClient = new DefaultHttpClient(); if (host.startsWith("https://")) { sslClient(httpClient); } return httpClient; } private static void sslClient(HttpClient httpClient) { try { SSLContext ctx = SSLContext.getInstance("TLS"); X509TrustManager tm = new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] xcs, String str) { } public void checkServerTrusted(X509Certificate[] xcs, String str) { } }; ctx.init(null, new TrustManager[] { tm }, null); SSLSocketFactory ssf = new SSLSocketFactory(ctx); ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); ClientConnectionManager ccm = httpClient.getConnectionManager(); SchemeRegistry registry = ccm.getSchemeRegistry(); registry.register(new Scheme("https", 443, ssf)); } catch (KeyManagementException ex) { throw new RuntimeException(ex); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException(ex); } } }
package com.lim.eth; public class EthConstant { //redis key 存储账户地址的pending交易集 用于计算nonce public static final String ADDRESS_TRAN_PENDING_KEY = "address.tran.pending.key-"; //etherscan api秘钥 public static final String ETHERSCAN_API_KEY = "******自己申请的秘钥******"; //ERC20_USDT合约地址 public static final String CONTRACTA_DDRESS = "0xdac17f958d2ee523a2206206994597c13d831ec7"; }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算