使用web3.js进行充值监听的两种方式
- 通过token event进行监听(只适合代币转账)
contract.events.Transfer({}, {
fromBlock: 0,
toBlock: 'latest',
}, async (error, event) => {
if (error) {
logger.error(error);
} else {
//获取event中转账信息
const to = event.returnValues.to.toLowerCase();
const bigValue = Big(event.returnValues.value);
const value = bigValue.div(1000000).toFixed(6);
const hash = event.transactionHash;
const user = await userService.findUidByEthAddress(to);
logger.debug(user);
if(user === null || user.uid === 0) {
return;
}
let encryptData = crypto.encrypt(JSON.stringify({
hash: event.transactionHash,
uid: user.uid,
value: value.toString(),
fromAddress: event.returnValues.from,
}), rechargeKey, rechargeIv);
const tx = await txService.findByHash(hash);
if(tx !== null) {
logger.info("交易重复提交");
return;
}
await txService.createTransaction(user.uid, hash, value.toString(), event.returnValues.from);
try {
const response = await fetchRequest(rechargeEthUsdtApi, encryptData);
if(response.code === 1) {
await txService.commitTransaction(hash);
logger.debug({msg: "状态提交成功", resCode: response.code});
}
} catch (e) {
logger.error(e);
await txService.invalidTransaction(hash);
logger.debug({msg: "状态提交成功", resCode: 0});
}
const mainAddress = await userService.mainAccount();
try {
logger.info("retrieve all ETH-USDT from child address");
await retrieveAllEthUsdt(user.uid, mainAddress);
logger.info("retrieve all ETH-USDT from child address successful");
} catch (e) {
logger.error(e);
logger.info("fail to retrieve all ETH-USDT from child address")
}
}
});
const watchTransaction = async () => {
//初始化lastblock
lastBlock = await getAsync(redisBlockCountKey);
logger.debug(lastBlock);
if (lastBlock === null) {
lastBlock = await web3.eth.getBlockNumber();
await setAsync(redisBlockCountKey, lastBlock);
return;
}
const currentBlock = await web3.eth.getBlockNumber();
logger.debug(currentBlock);
//初始化
if (currentBlock - lastBlock > 50) {
await setAsync(redisBlockCountKey, currentBlock);
return;
}
await setAsync(redisBlockCountKey, currentBlock + 1);
const mainAddress = await userService.mainAccount();
//扫块
for (let i = lastBlock; i < currentBlock + 1; i++) {
const block = await web3.eth.getBlock(i, true);
const txs = block.transactions;
logger.info("txCount: " + txs.length);
for (let j = 0; j < txs.length; j++) {
const tx = txs[j];
const toAddress = tx.to.toLowerCase();
let user;
try {
user = await userService.findUidByEthAddress(toAddress);
} catch (e) {
continue;
}
//eth交易处理
if (user !== null && user.uid !== 0 && tx.from !== mainAddress) {
logger.debug(user);
const hash = tx.hash;
const findTx = await rechargeInfoService.checkHash(hash);
if (findTx !== null) {
logger.debug("交易重复提交");
continue;
}
const bigValue = Big(tx.value).div('1e+18');
//提交服务器
let encryptData = crypto.encrypt(JSON.stringify({
hash: hash,
uid: user.uid,
value: bigValue,
fromAddress: tx.from,
cid: 1
}), rechargeKey, rechargeIv);
await rechargeInfoService.createRechargeInfo(user.uid, hash, bigValue.toString(), tx.from, 1);
let response;
try {
response = await fetchRequest(rechargeApi, encryptData);
} catch (e) {
await rechargeInfoService.invalidTransaction(hash);
logger.debug({msg: "状态提交成功", resCode: 0});
}
if (response.code === 1) {
await rechargeInfoService.commitTransaction(hash);
logger.debug({msg: "状态提交成功", resCode: response.code});
} else {
await rechargeInfoService.invalidTransaction(hash);
logger.debug({msg: "状态提交成功", resCode: response.code});
}
const ethBalance = await web3.eth.getBalance(toAddress);
//提取子账户中的eth
if(ethBalance > web3.utils.toWei("0.005", "ether")) {
try {
logger.info("retrieve ETH from child address");
await retrieveAllEth(user.uid, mainAddress);
logger.info("retrieve ETH from child address successful")
} catch (e) {
logger.error(e);
logger.info("fail to retrieve ETH from child address");
}
}
continue;
}
const input = tx.input;
//token交易处理
if (input.length === 138 && input.substr(0, 10) === "0xa9059cbb") {
const addr = input.substring(34, 74);
const user = await userService.findUidByEthAddress("0x" + addr);
if (user !== null && user.uid !== 0 && tx.from !== mainAddress) {
logger.debug(user);
const hash = tx.hash;
//检查token是否在数据库内
const token = await coinService.findByCoinAddress(toAddress);
if (token === null) {
continue;
}
//检查token转账是否有效
const transactionReceipt = await web3.eth.getTransactionReceipt(hash);
if (transactionReceipt.logs.length === 0) {
continue;
}
//创建合约对象
const contract = await new web3.eth.Contract(abi, toAddress);
const tokenValue = web3.utils.hexToNumberString(input.substring(74, input.length));
const bigValue = Big(tokenValue).div('1e+' + token.decimal);
// 保存数据库
await rechargeInfoService.createRechargeInfo(user.uid, hash, bigValue.toString(), tx.from, token.cid);
// 提取子账户中的token
try {
logger.info("retrieve coin from child address");
await retrieveAllCoin(user.uid, mainAddress, contract);
logger.info("retrieve coin from child address successful");
} catch (e) {
logger.error(e);
logger.info("fail to retrieve coin from child address");
}
// 提交服务器
let encryptData = crypto.encrypt(JSON.stringify({
hash: hash,
uid: user.uid,
value: bigValue.toString(),
fromAddress: tx.from,
cid: token.cid
}), rechargeKey, rechargeIv);
let response;
try {
response = await fetchRequest(rechargeApi, encryptData);
} catch (e) {
await rechargeInfoService.invalidTransaction(hash);
logger.debug({msg: "状态提交成功", resCode: 0});
}
if (response.code === 1) {
await rechargeInfoService.commitTransaction(hash);
logger.debug({msg: "状态提交成功", resCode: response.code});
} else {
await rechargeInfoService.invalidTransaction(hash);
logger.debug({msg: "状态提交成功", resCode: response.code});
}
}
}
}
}
};