비트코인의 다음 주기의 target 값을 계산하는 golang 실현

구현 코드:
func CalNextTarget(start, end *utils.BlockDiff) (*big.Int,error) {
	if int64(start.Height) % 2016 != 0 {
		return nil,errors.New("start height % 2016 should be 0")
	}
	if end.Height != (start.Height+2015) {
		return nil,errors.New("end height should == start height + 2016")
	}

	timeVal := float64( end.Timestamp - start.Timestamp ) // : 
	fmt.Println("actual timeval:", timeVal)
	expectTimeVal := float64( 2016*10*60 ) // 2016 , : 
	fmt.Println("expect timeval:", expectTimeVal)
	rate := float64(timeVal)/float64(expectTimeVal)
	if rate > 4 {
		rate = 4
	}
	if rate < 0.25 {
		rate = 0.25
	}
	var (
		currTarget *big.Int
		nextTarget *big.Int
		maxTargetInBigInt *big.Int
		maxTarget decimal.Decimal
	)
	currTarget = Bits2Target(uint32(end.Bits))

	maxTargetInBigInt,_ = new(big.Int).SetString("00000000ffff0000000000000000000000000000000000000000000000000000", 16)
	maxTarget = decimal.NewFromBigInt(maxTargetInBigInt, 0)
	ret := decimal.NewFromBigInt(currTarget, 0).Mul(decimal.NewFromFloat(rate))//
	if ret.GreaterThan(maxTarget) {// 
		nextTarget = maxTarget.BigInt()
	} else {
		nextTarget = ret.BigInt()
	}
	return nextTarget, nil
}

 
테스트 코드:
func TestCalNextTarget(t *testing.T) {
	//t.SkipNow()
	t.Run("test next target", func(t *testing.T) {
		var (
			start *utils.BlockDiff
			end *utils.BlockDiff
			want *utils.BlockDiff
			nextTarget *big.Int
			gotBits uint32
			err error
			nextTargetInBytes []byte
		)

		for i:=14; i<100; i++ {
			startHeight := i*2016
			fmt.Println("startHeight:", startHeight)
			if start,err = utils.GetBlockInfo(uint64(startHeight));err != nil {
				t.Error(err)
				return
			}
			if end,err = utils.GetBlockInfo(uint64(startHeight+2015));err != nil {
				t.Error(err)
				return
			}
			if want,err = utils.GetBlockInfo(uint64(startHeight+2016));err != nil {
				t.Error(err)
				return
			}

			if nextTarget,err =CalNextTarget(start, end);err != nil {
				t.Error(err)
				return
			}

			if nextTargetInBytes, err = ZipTarget(nextTarget); err != nil {
				t.Error(err)
				return
			}
			gotBits = uint32(binary.LittleEndian.Uint32(nextTargetInBytes))
			if gotBits != uint32(want.Bits) {
				t.Error("wrong bits")
				t.Errorf("want:%x
", uint32(want.Bits)) t.Errorf("got:%x
", gotBits) return } } }) }

테스트 코드의utils.GetBlockInfo 함수는 내 데이터베이스에서 읽은 데이터이고 데이터베이스에 있는 데이터는 내가 사전에 인터넷에서 얻은 비트코인 블록체인 데이터이다.그래서 여기는 나누지 않겠습니다.
 
(전문 끝)
참고 자료:
https://learnmeabitcoin.com/guide/target

좋은 웹페이지 즐겨찾기