主页 > 钱包imtoken官网 > Web3j通过合约地址监听转账事件获取以太坊交易数据

Web3j通过合约地址监听转账事件获取以太坊交易数据

钱包imtoken官网 2023-01-17 12:10:57

Web3j通过合约地址监听转账事件获取以太坊交易数据

We3j

web3j 是一个轻量级的 Java 库以太坊交易信息获取,用于在以太坊网络上集成客户端(节点)。

核心功能

业务需求:分析区块链转账记录,获取交易信息进行进一步分析。

原代码以太坊交易信息获取,使用web3j访问以太坊全节点,通过合约地址监听转账事件,获取交易记录。

注意:注意版本问题。 不同版本事件的构造参数列表不同。

	
		org.web3j
		core
		3.4.0
  	

GitHub:链接。 欢迎加星

@Service
public class MonitorTransferService {
    private static final Logger LOG = LoggerFactory.getLogger(MonitorTransferService.class);
    private Web3j web3j;
    private ThreadLocal> blockNumberSet = ThreadLocal.withInitial(HashSet::new);
    @Value("${ipcSocketPath}")
    private String ipcSocketPath;

以太坊获取交易数据_以太坊交易信息获取_以太坊内部转账交易

@PostConstruct public void init() { // web3j = Web3j.build(new HttpService()); //RPC方式 web3j = Web3j.build(new UnixIpcService(ipcSocketPath)); //IPC方式 } /** * 监听合约(分步) */ public void contractFilterOfStep(MonitorTransferRequest monitorTransferRequest) { new Thread(() -> { try { BigInteger blockNumber = getBlockNumber(); LOG.info("BlockChainNumber={}", blockNumber); BigInteger startBlock = new BigInteger(monitorTransferRequest.getFirstBlock()); BigInteger step = new BigInteger("100"); assert blockNumber != null; int num = Integer.parseInt(String.valueOf(blockNumber.subtract(startBlock).divide(step))); for (int i = 0; i < num; i++) { // 监听合约(分步) contractFilterStep(monitorTransferRequest, startBlock, startBlock.add(step)); startBlock = startBlock.add(step); } // 监听合约

以太坊交易信息获取_以太坊内部转账交易_以太坊获取交易数据

contractFilter(monitorTransferRequest, startBlock); } catch (NumberFormatException e) { LOG.error("监控合约异常终止,e={}", e.getMessage()); } }).start(); } /** * 监听合约 */ private void contractFilter(MonitorTransferRequest monitorTransferRequest, BigInteger startBlock) { Event event = new Event("Transfer", Arrays.asList( new TypeReference
() { }, new TypeReference
() { }), Collections.singletonList(new TypeReference() { })); EthFilter filter = new EthFilter( DefaultBlockParameter.valueOf(startBlock), DefaultBlockParameterName.LATEST, monitorTransferRequest.getContractAddress()); filter.addSingleTopic(EventEncoder.encode(event));

以太坊获取交易数据_以太坊交易信息获取_以太坊内部转账交易

// 监听并处理 contractExtract(filter); } /** * 监听并处理 */ private void contractExtract(EthFilter filter) { Subscription subscription = web3j.ethLogObservable(filter).subscribe(log -> { BigInteger blockNumber = log.getBlockNumber(); // 提取转账记录 LOG.info("BlockNumber=", blockNumber); blockNumberSet.get().add(blockNumber); List topics = log.getTopics(); String fromAddress = topics.get(1); String toAddress = topics.get(2); String value = log.getData(); String timestamp = ""; try { EthBlock ethBlock = web3j.ethGetBlockByNumber(DefaultBlockParameter.valueOf(log.getBlockNumber()), false).send(); timestamp = String.valueOf(ethBlock.getBlock().getTimestamp()); } catch (IOException e) { LOG.warn("Block timestamp get failure,block number is {}", log.getBlockNumber());

以太坊获取交易数据_以太坊内部转账交易_以太坊交易信息获取

LOG.error("Block timestamp get failure,{}", e); } TransferRecord transferRecord = new TransferRecord(); transferRecord.setFromAddress("0x" + fromAddress.substring(26)); transferRecord.setToAddress("0x" + toAddress.substring(26)); transferRecord.setValue(new BigDecimal(new BigInteger(value.substring(2), 16)).divide(BigDecimal.valueOf(1000000000000000000.0), 18, BigDecimal.ROUND_HALF_EVEN)); transferRecord.setTimeStamp(timestamp); }); // subscription.unsubscribe(); } /** * 监听合约(分步) */ private void contractFilterStep(MonitorTransferRequest monitorTransferRequest, BigInteger startBlock, BigInteger endBlock) { Event event = new Event("Transfer", Arrays.asList( new TypeReference
() { }, new TypeReference
() { }), Collections.singletonList(new TypeReference() { }));

以太坊交易信息获取_以太坊内部转账交易_以太坊获取交易数据

EthFilter filter = new EthFilter( DefaultBlockParameter.valueOf(startBlock), DefaultBlockParameter.valueOf(endBlock), monitorTransferRequest.getContractAddress()); filter.addSingleTopic(EventEncoder.encode(event)); // 监听并处理 contractExtract(filter); } /** * 区块数量 */ private BigInteger getBlockNumber() { EthBlockNumber send; try { send = web3j.ethBlockNumber().send(); return send.getBlockNumber(); } catch (IOException e) { LOG.warn("请求区块链信息异常 >> 区块数量,{}", e); } return null; }

GitHub:链接。 欢迎加星

本文来自: