掃塊監(jiān)聽邏輯
跑定時任務,每隔固定時間執(zhí)行一次輪詢,這里我采用的間隔時間是距上一次執(zhí)行完后45秒;
定時任務:從上一次輪詢的最后區(qū)塊開始掃描,獲取每個區(qū)塊中所有交易,進行對應查詢數據庫操作和判斷操作,執(zhí)行完后記錄輪詢到的區(qū)塊高度,方便下一次查詢;
相關依賴
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>4.0.3</version>
</dependency>
- 以下是使用spring管理的定時任務方法案例:
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.methods.response.EthBlock;
import org.web3j.protocol.http.HttpService;
import java.io.IOException;
import java.math.BigInteger;
@Component
public class TransactionWatcherExample {
private Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
//上次輪詢到的塊高度
private BigInteger lastBlockNumber;
/**
* 掃塊監(jiān)聽eth交易,每45秒一次輪詢
* @throws IOException
*/
@Scheduled(fixedDelay = 45 * 1000)
public void watchEthTransaction() throws IOException {
//獲取當前塊高度
BigInteger currentBlockNumber = web3j.ethBlockNumber().send().getBlockNumber();
//運行初始化
if (lastBlockNumber == null || currentBlockNumber.subtract(lastBlockNumber).compareTo(BigInteger.valueOf(100)) > 0) {
lastBlockNumber = BigInteger.valueOf(currentBlockNumber.longValue());
return;
}
long futureBlockNum = currentBlockNumber.intValue() + 1;
//遍歷區(qū)塊
for (int i = lastBlockNumber.intValue(); i < futureBlockNum; i++) {
//獲取block
EthBlock.Block block = web3j.ethGetBlockByNumber(DefaultBlockParameter.valueOf(BigInteger.valueOf(i)), true).send().getBlock();
if (block == null) {
continue;
}
// 遍歷block中的交易
for (EthBlock.TransactionResult tx : block.getTransactions()) {
if (tx instanceof EthBlock.TransactionObject) {
//transaction: 塊中的單筆交易
EthBlock.TransactionObject transaction = (EthBlock.TransactionObject) tx;
// todo 交易判斷和處理邏輯
}
}
}
lastBlockNumber = BigInteger.valueOf(futureBlockNum);
}
}