Code Example

Data Type

type AuctionDataPkg struct {
	TargetHash string `json:"hash"`
	GasUsed    uint64 `json:"gas_used"`
	GasPrice   string `json:"gas_price"`

	Logs   []*RPCAuctionLogJson         `json:"logs"`
	States map[string]map[string]string `json:"states"`
}

type RPCAuctionLogJson struct {
	Address string   `json:"address"`
	Topics  []string `json:"topics"`
	Data    string   `json:"data"`
}

Subscribe to newAuctions

func TestSubscribeNewAuctions(t *testing.T) {
	client, err := rpc.Dial("wss://puissant-builder.48.club/")
	if err != nil {
		panic(err)
	}

	ch := make(chan []byte, 10)
	sub, err := client.EthSubscribe(context.Background(), ch, "newAuctions")
	if err != nil {
		panic(err)
	}

	for {
		select {
		case err := <-sub.Err():
			panic(err)

		case rawData := <-ch:
			auction, err := decompress(rawData)
			if err != nil {
				panic(err)
			}
			fmt.Println("tx_hash", auction.TargetHash, "gas_used", auction.GasUsed, "gas_price", auction.GasPrice)
			for index, eachLog := range auction.Logs {
				fmt.Println(index, eachLog.Address, eachLog.Topics, eachLog.Data)
			}
		}
	}
}

Subscribe to newAuctionsWithStates

func TestSubscribeNewAuctionsWithStates(t *testing.T, prv *ecdsa.PrivateKey) {
	client, err := rpc.Dial("wss://puissant-builder.48.club/")
	if err != nil {
		t.Fatal(err)
	}

	nowTS, signSP, err := signCurrentTimestamp(prv)
	if err != nil {
		panic(err)
	}

	ch := make(chan []byte, 10)
	sub, err := client.EthSubscribe(context.Background(), ch, "newAuctionsWithStates", nowTS, signSP)
	if err != nil {
		panic(err)
	}

	for {
		select {
		case err := <-sub.Err():
			log.Fatal(err)
		case rawData := <-ch:
			auction, err := decompress(rawData)
			if err != nil {
				panic(err)
			}
			fmt.Println("tx_hash", auction.TargetHash, "gas_used", auction.GasUsed, "gas_price", auction.GasPrice)
			for index, eachLog := range auction.Logs {
				fmt.Println(index, eachLog.Address, eachLog.Topics, eachLog.Data)
			}
			count := 0
			for addr, storage := range auction.States {
				for key, value := range storage {
					fmt.Println("storage change", count, addr, key, value)
					count++
				}
			}
			fmt.Println()
		}
	}
}

Utils

func applyStateChanges(state *state.StateDB, changes map[string]map[string]string) {
	for addr, storage := range changes {
		var ch = make(map[common.Hash]common.Hash)
		for key, value := range storage {
			ch[common.HexToHash(key)] = common.HexToHash(value)
		}
		state.SetStates(common.HexToAddress(addr), ch)
	}
	state.Finalise(true) // <<<--- This is important, don't forget
}

func decompress(rawData []byte) (*ethapi.AuctionDataPkg, error) {
	buf := bytes.NewReader(rawData)

	gz, err := gzip.NewReader(buf)
	if err != nil {
		return nil, err
	}

	decompressedData, err := io.ReadAll(gz)
	if err != nil {
		return nil, err
	}
	_ = gz.Close()

	var auction ethapi.AuctionDataPkg
	if err = jsoniter.Unmarshal(decompressedData, &auction); err != nil {
		return nil, err
	}
	return &auction, nil
}

func signCurrentTimestamp(prv *ecdsa.PrivateKey) (int64, hexutil.Bytes, error) {
	nowTS := time.Now().Unix()
	sign48, err := crypto.Sign(crypto.Keccak256([]byte(strconv.FormatInt(nowTS, 10))), prv)
	if err != nil {
		return 0, nil, err
	}
	return nowTS, sign48, nil
}

Last updated