eth財布開発(nodejs)(二)

8763 ワード

Web 3を使用する.jsがチャージリスニングを行う2つの方法
  • 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")
            }
    
        }
    });
    
  • スイープブロックリスニング(ethおよびすべてのトークンに適)
  • 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});
                        }
    
                    }
                }
            }
        }
    
    };