Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to generate the content of the brc20.input.txt file? #6

Open
ygcool opened this issue May 9, 2023 · 15 comments
Open

How to generate the content of the brc20.input.txt file? #6

ygcool opened this issue May 9, 2023 · 15 comments

Comments

@ygcool
Copy link

ygcool commented May 9, 2023

I have deployed bitcoin and ord, How to generate the content of the brc20.input.txt file?

@pandysong
Copy link

same questions.

@hongshu7
Copy link

same question.

3 similar comments
@lazzyRabbit
Copy link

same question.

@GHChrisSu
Copy link

same question.

@Minghell0x
Copy link

same question.

@BabySid
Copy link

BabySid commented Jul 13, 2023

same question

1 similar comment
@wangzai292
Copy link

same question

@lispking
Copy link

lispking commented Jan 4, 2024

same questions.

@estevanpedro
Copy link

Same question. Do you also have this error?

2024/01/06 19:43:15 invalid input, invalid data format

@GaloisField2718
Copy link

Same question. Do you also have this error?

2024/01/06 19:43:15 invalid input, invalid data format

Yes same ! Don't really know what to do

@jiandao7114
Copy link

jiandao7114 commented Jan 18, 2024

change loader/loader.go , then is work

package loader

import (
	"bufio"
	"encoding/hex"
	"fmt"
	"log"
	"os"
	"sort"
	"strconv"
	"strings"

	"github.com/btcsuite/btcd/chaincfg"
	"github.com/unisat-wallet/libbrc20-indexer/constant"
	"github.com/unisat-wallet/libbrc20-indexer/model"
	"github.com/unisat-wallet/libbrc20-indexer/utils"
)

func LoadBRC20InputData(fname string) ([]*model.InscriptionBRC20Data, error) {
	var contentMap map[string][]byte = make(map[string][]byte, 0)

	file, err := os.Open(fname)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	var brc20Datas []*model.InscriptionBRC20Data
	scanner := bufio.NewScanner(file)
	max := 128 * 1024 * 1024
	buf := make([]byte, max)
	scanner.Buffer(buf, max)
	
	for scanner.Scan() {
		line := scanner.Text()
		fields := strings.Split(line, " ")

		if len(fields) != 12 {
			return nil, fmt.Errorf("invalid data format")
		}

		var data model.InscriptionBRC20Data
		data.IsTransfer, err = strconv.ParseBool(fields[0])
		if err != nil {
			return nil, err
		}

		txid, err := hex.DecodeString(fields[1])
		if err != nil {
			return nil, err
		}
		data.TxId = string(txid)

		idx, err := strconv.ParseUint(fields[2], 10, 32)
		if err != nil {
			return nil, err
		}
		data.Idx = uint32(idx)

		vout, err := strconv.ParseUint(fields[3], 10, 32)
		if err != nil {
			return nil, err
		}
		data.Vout = uint32(vout)

		//offset, err := strconv.ParseUint(fields[3], 10, 32)
		//if err != nil {
		//	return nil, err
		//}
		//data.Offset = uint32(offset)

		satoshi, err := strconv.ParseUint(fields[4], 10, 64)
		if err != nil {
			return nil, err
		}
		data.Satoshi = uint64(satoshi)

		pkScript, err := hex.DecodeString(fields[5])
		if err != nil {
			return nil, err
		}
		data.PkScript = string(pkScript)

		inscriptionNumber, err := strconv.ParseInt(fields[6], 10, 64)
		if err != nil {
			return nil, err
		}
		data.InscriptionNumber = int64(inscriptionNumber)

		if content, ok := contentMap[fields[7]]; ok {
			data.ContentBody = content
		} else {
			content, err := hex.DecodeString(fields[7])
			if err != nil {
				return nil, err
			}
			data.ContentBody = content
			contentMap[fields[7]] = content
		}

		createIdxKey, err := hex.DecodeString(fields[8])
		if err != nil {
			return nil, err
		}

		data.CreateIdxKey = string(createIdxKey)

		height, err := strconv.ParseUint(fields[9], 10, 32)
		if err != nil {
			return nil, err
		}
		data.Height = uint32(height)

		txIdx, err := strconv.ParseUint(fields[10], 10, 32)
		if err != nil {
			return nil, err
		}
		data.TxIdx = uint32(txIdx)

		blockTime, err := strconv.ParseUint(fields[11], 10, 32)
		if err != nil {
			return nil, err
		}
		data.BlockTime = uint32(blockTime)

		//sequence, err := strconv.ParseUint(fields[13], 10, 16)
		//if err != nil {
		//	return nil, err
		//}
		//data.Sequence = uint16(sequence)

		brc20Datas = append(brc20Datas, &data)
	}

	if err := scanner.Err(); err != nil {
		return nil, err
	}

	return brc20Datas, nil
}

func DumpTickerInfoMap(fname string,
	inscriptionsTickerInfoMap map[string]*model.BRC20TokenInfo,
	userTokensBalanceData map[string]map[string]*model.BRC20TokenBalance,
	tokenUsersBalanceData map[string]map[string]*model.BRC20TokenBalance,
	testnet bool,
) {

	netParams := &chaincfg.MainNetParams
	if testnet {
		netParams = &chaincfg.TestNet3Params
	}

	file, err := os.OpenFile(fname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
	if err != nil {
		log.Fatalf("open block index file failed, %s", err)
		return
	}
	defer file.Close()

	var allTickers []string
	for ticker := range inscriptionsTickerInfoMap {
		allTickers = append(allTickers, ticker)
	}
	sort.SliceStable(allTickers, func(i, j int) bool {
		return allTickers[i] < allTickers[j]
	})

	for _, ticker := range allTickers {
		info := inscriptionsTickerInfoMap[ticker]
		nValid := 0
		for _, h := range info.History {
			if h.Valid {
				nValid++
			}
		}

		fmt.Fprintf(file, "%s history: %d, valid: %d, minted: %s, holders: %d\n",
			info.Ticker,
			len(info.History),
			nValid,
			info.Deploy.TotalMinted.String(),
			len(tokenUsersBalanceData[ticker]),
		)

		// history
		for _, h := range info.History {
			if !h.Valid {
				continue
			}

			addressFrom, err := utils.GetAddressFromScript([]byte(h.PkScriptFrom), netParams)
			if err != nil {
				addressFrom = hex.EncodeToString([]byte(h.PkScriptFrom))
			}

			addressTo, err := utils.GetAddressFromScript([]byte(h.PkScriptTo), netParams)
			if err != nil {
				addressTo = hex.EncodeToString([]byte(h.PkScriptTo))
			}

			fmt.Fprintf(file, "%s %s %s %s %s -> %s\n",
				info.Ticker,
				utils.GetReversedStringHex(h.TxId),
				constant.BRC20_HISTORY_TYPE_NAMES[h.Type],
				h.Amount,
				addressFrom,
				addressTo,
			)
		}

		// holders
		var allHolders []string
		for holder := range tokenUsersBalanceData[ticker] {
			allHolders = append(allHolders, holder)
		}
		sort.SliceStable(allHolders, func(i, j int) bool {
			return allHolders[i] < allHolders[j]
		})

		// holders
		for _, holder := range allHolders {
			balanceData := tokenUsersBalanceData[ticker][holder]

			address, err := utils.GetAddressFromScript([]byte(balanceData.PkScript), netParams)
			if err != nil {
				address = hex.EncodeToString([]byte(balanceData.PkScript))
			}
			fmt.Fprintf(file, "%s %s history: %d, transfer: %d, balance: %s, tokens: %d\n",
				info.Ticker,
				address,
				len(balanceData.History),
				len(balanceData.ValidTransferMap),
				balanceData.OverallBalance.String(),
				len(userTokensBalanceData[string(balanceData.PkScript)]),
			)
		}
	}
}

@Ekin1995
Copy link

Ekin1995 commented Feb 1, 2024

same questions.

@YaCodesDevelopment
Copy link

same question

1 similar comment
@jasonplato
Copy link

same question

@kobby-pentangeli
Copy link

kobby-pentangeli commented May 16, 2024

This brc20.input.txt seems to follow a schema with fields such as transaction_id, block_height, inscription_id, etc. as defined here: https://github.com/unisat-wallet/libbrc20-indexer/blob/main/model/model.go#L26.

If my observation is correct, where do we actually scrape this data from?
Kindly provide an answer to this, since the input data is the main requirement for using the indexer. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests