เป้าหมาย (Target) ใช้ในการขุด มันตัวเลขที่ตัวเลข Hash ของบล็อกจะต้องอยู่ต่ำกว่าบล็อกเพื่อที่จะเพิ่มข้อมูลเข้าไปบน Blockchain
เป้ามาย (Target) จะถูกปรับทุกๆ 2016 บล็อก (หรือประมาณทุกๆ 2 สัปดาห์) เพื่อที่จะยืนยันว่าบล็อกถูกขุดขึ้นมาทุกๆ 10 นาทีโดยเฉลี่ย เพราะฉะนั้นก็จะทำให้เวลาในการสร้างบล็อกและการออก Bitcoin ใหม่เข้าสู่ระบบ (หรือเรียกอีกอย่างหนึ่งว่ารางวัลในการขุด) มีความสม่ำเสมอและแน่นอน
เพื่อที่จะทำการชดเชยสำหรับการเพิ่มความเร็วของฮาร์ดแวร์และดอกเบี้ยที่แตกต่างกันไปให้ Node ที่กำลังทำงานอยู่บนระบบ ค่าความยาก (difficulty) ของระบบฉันทามติ Proof of work จะถูกกำหนดโดยเป้าหมาย (target) ค่ากำหนดเคลื่อนที่และตัวเลขเฉลี่ย ของบล็อกแต่ละชั่วโมง ถ้ามีการสร้างอย่างรวดเร็วเกินไป ค่าความยาก (difficulty) ก็จะเพิ่มขึ้น – Satoshi Nakamoto
2. เป้าหมาย (Target) ถูกคำนวณได้อย่างไร
เป้าหมาย (Target) ของบล็อกแรกจะถูกตั้งค่าไว้ที่
00000000ffff0000000000000000000000000000000000000000000000000000
หลังจากมีบล็อกเกิดขึ้น 2016 บล็อก Node แต่ละ Node ก็จะดูที่เวลาระหว่างบล็อก 2016 บล็อกล่าสุดและจะประมาลผลว่าบล็อกเหล่านั้นถูกขุดเร็วกว่าหรือช้ากว่าค่าเฉลี่ย 10 นาที
หากบล็อกที่อยู่ในช่วงเวลาระหว่างนี้ถูกขุดเร็วกว่า 10 นาที เป้าหมาย (Target) จะปรับลงมาเพื่อที่จะทำให้การหาค่าเป้าหมาย (Target) ในช่วงของบล็อกต่อไปมีความยากมากขึ้น
อธิบายอย่างง่ายก็คือ หากบล็อกถูกขุดได้ช้าลงกว่า 10 นาที ค่าเป้าหมาย (Target) ก็จะถูกปรับให้สูงขึ้นเพื่อให้การคำนวณหาค่าที่ต่ำกว่าเป้าหมาย (Target) ง่ายขึ้นในช่วงเวลาต่อไปของบล็อก
ผลลัพธ์ก็คือ แต่ละ Node จะคำนวณเป้าหมาย (Target) เป็นประจำเพื่อที่จะควบคุมให้เกิดบล็อกใหม่ทุกๆ ช่วงเวลา 10 นาที แม้ว่าจะมีนักขุดเข้ามาและออกจากเครือข่ายเรื่อยๆ
อะไรที่ทำให้การขุดบล็อกเร็วกว่าหรือช้ากว่า 10 นาที
เอาล่ะ ก่อนอื่นเลยต้องบอกว่าการขุดนั้นไม่สามารถคาดการณ์ได้ เพราะฉะนั้นคุณไม่มีทางรู้ว่าเมื่อไหร่นัดขุดจะหาบล็อกต่อไปกับตัวเลข Hash ของบล็อกที่อยู่ต่ำกว่าเป้าหมาย (target) ได้
ต่อมา (และสำคัญมาก) นักขุดสามารถเข้าร่วมหรือออกจากระบบได้เสมอ ซึ่งจะส่งผลกับความเป็นไปได้ที่บล็อกใหม่จะถูกขุดขึ้นมาทุกๆ 10 นาที ยิ่งมีนักขุดอยู่บนระบบมากเท่าไหร่ ก็ยิ่งมีการคำนวณเลข Hash มากขึ้น เช่นเดียวกับความเป็นไปได้ที่บล็อกใหม่จะถูกขุดขึ้นมาในระยะเวลาไม่ถึง 10 นาที
3. ทุก Node จะกระจายข้อมูลเป้าหมาย (Target) เดียวกันหรือไม่
แต่ละ Node บนระบบจะทำงานกันเป็นเอกเทศ เพราะฉะนั้น จะไม่มีการส่ง “ค่าเป้าหมาย (Target) เพียงค่าเดียว” กระจายไปทั่วเครือข่าย
อย่างไรก็ตาม เพราะว่า Node ทุก Node จะเอาห่วงโซ่ที่ยาวที่สุดของบล็อกมาปรับใช้บนเครือข่าย Blockchain ของตัวเอง พวกมันอาจจะนำเอาเป้าหมาย (target) เดียวกันกับคนอื่นมาคำนวณในท้ายที่สุด เพราะฉะนั้น Node ทั้งหมดอาจจะกระจายค่าเป้าหมาย (target) เดียวกันในท้ายที่สุด
ยกตัวอย่างเช่น เมื่อคุณใช้งานโปรแกรม Bitcoin เป็นครั้งแรก Node ของคุณจะทำการดาวน์โหลดบล็อกแรกและคำนวณค่าเป้าหมายเป้าหมาย (target) เพื่อเดินหน้าทำงานต่อไป และเป็นเพราะว่าคุณได้รับบล็อกเดียวกันกับคนอื่นๆ ในเครือข่าย คุณก็อาจจะคำนวณค่าเป้าหมาย (target) ปัจจุบันเดียวกัน
นอกจากนี้ Node ทั้งหมดจะดำเนินการกระจายภาพของ Blockchain อย่างต่อเนื่อง (พวกมันจะนำเอาห่วงโซ่ของบล็อกที่ยาวที่สุดที่สามารถใช้งานได้มาปรับใช้งานเสมอ) จากนั้น Node ก็จะคำนวณค่าเป้าหมาย (Target) เดียวกันเมื่อมีบล็อกใหม่เกิดขึ้นอย่างต่อเนื่อง
ผลลัพธ์ก็คือ แทนที่ข้อเท็จจริงที่ว่า Node ทั้งหลายจะคำนวณเป้าหมาย (Target) อย่างเป็นเอกเทศ พวกมันจะใช้ Blockchain ร่วมกันและคำนวณค่าเป้าหมาย (Target) เดียวกับ Node อื่นๆ
ทุกๆ คนจะใช้การคำนวณเดียวกันในข้อมูลห่วงโซ่เดียวกัน เพราะฉะนั้นพวกมันจะได้รับผลลัพธ์ที่สอดคล้องกันบนห่วงโซ่ – Satoshi Nakamoto
4. ทำไม Bitcoin ต้องใช้เป้าหมาย (Target)
เป้าหมาย (Target) จะควบคุมความเร็วของการเกิดบล็อกใหม่บน blockchain
เป้าหมาย (Target) จะมีประโยชน์อยู่สองข้อด้วยกัน
4.1 ให้เวลาบล็อกในการกระจายข้อมูลไปทั่วเครือข่าย
หลักการก็คือการให้นักขุดทำงานเพื่อขยายห่วงโซ่ของบล็อกเดียวกันให้มากที่สุดเท่าที่จะเป็นไปได้ เพื่อให้หลักการดังกล่าวเป็นจริง เราต้องให้เวลาบล็อกใหม่ๆ ในการกระจายข้อมูลไปทั่วเครือข่ายก่อนที่บล็อกใหม่จะถูกขุดขึ้นมา
หากบล็อกถูกขุดขึ้นมาเร็วกว่าที่มันจะกระจายข้อมูลไปทั่วเครือข่าย ก็จะกลายเป็นว่านักขุดอาจจะไปทำงานบนห่วงโซ่อื่นแข่งกันอยู่เสมอ มีเพียงห่วงโซ่เดียวเท่านั้นที่จะเป็นห่วงโซ่ที่ยาวที่สุด เพราะฉะนั้นนักขุดบางส่วนอาจจะเสียพลังงานในการสร้างบล็อกบนห่วงโซ่คู่แข่งซึ่งท้ายที่สุดแล้วอาจจะถูกทิ้งไว้ข้างหลังได้ตามเงื่อนไขของการปรับโครงสร้างของห่วงโซ่ใหม่
จากนั้น เวลาที่ล่าช้านี้ระหว่างบล็อกทำให้พวกมันสามารถกระจายผ่านเครือข่าย นักขุดที่มากขึ้นจะสามารถนำเอาห่วงโซ่ที่ยาวที่สุดที่สามารถใช้งานได้ไปปรับใช้ ซึ่งจะทำให้เครือข่ายของพลังงานการขุดมีประสิทธิภาพในการทำงานและขยายห่วงโซ่เดียวกันของบล็อกได้มากขึ้น
ถ้าการกระจายและส่งต่อข้อมูลเริ่มช้ากว่าที่คาดการณ์ไว้ เวลาของเป้าหมาย (Target) ระหว่างบล็อกอาจจะต้องเพิ่มขึ้นเพื่อหลีกเลี่ยงการเสียทรัพยากรไปโดยเปล่าประโยชน์ เราต้องการให้บล็อกกระจายออกไปตามปกติในเวลาที่น้อยกว่าเวลาที่ใช้ในการสร้างมันขึ้นมา มิฉะนั้น Node จะใช้เวลามากเกินไปในการทำงานกับบล็อกที่ไม่อัพเดท – Satoshi Nakamoto
4.2 ความสม่ำเสมอของการออก Bitcoin ใหม่บนเครือข่าย
Bitcoin เป็นสกุลเงิน เพราะฉะนั้นการควบคุมอัตราการออก Bitcoin เข้าไปในระบบก็จะช่วยให้มีความมั่นคง
ต้องขอบคุณสำหรับเป้าหมาย (target) ที่จะทำให้คุณมั่นใจได้ว่า Bitcoin ใหม่จะถูกสร้างในอัตราที่คาดการณ์ได้ตราบเท่าที่เครือข่ายกำลังทำงานอยู่
เหรียญจะต้องถูกกระจายออกไปไม่ทางใดก็ทางหนึ่งเสียก่อน และการมีอัตราที่คงที่ก็น่าจะเป็นสูตรที่ดีที่สุด – Satoshi Nakamoto
5. ทำไมจะต้องเว้นระยะเวลาระหว่างบล็อกอยู่ที่ 10 นาที?
ฉันไม่คิดว่าจะมีใครรู้ว่าทำไมจะต้องกำหนดระยะเวลาเป็น 10 นาทีเท่านั้นด้วย ยกเว้น Satoshi
ฉันทำได้แค่เพียงเดาว่าระยะเวลาดังกล่าวดูจะนานมากพอที่จะทำให้บล็อกกระจายข้อมูลข้ามเครือข่าย (เพื่อลดการจัดระเบียบโครงสร้างใหม่ของห่วงโซ่) และก็เป็นระยะเวลาที่สั้นมากพอที่คุณจะไม่ต้องรอนานเกินไปให้การทำธุรกรรมใหม่ถูกขุดเข้าไปใน Blockchain และเลข 10 ก็ดูกลมๆ ดีด้วย
Commands
bitcoin-cli getblocktemplate
นี้เป็นวิธีการที่ง่ายที่สุดในการได้รับเป้าหมาย (Target) ปัจจุบัน เมื่อคุณร้องขอเทมเพลตของบล็อกสำหรับการขุดมันขึ้นมา และมันยังกลับคืนสู่เป้าหมาย (Target) ปัจจุบันอีกด้วย
$ bitcoin-cli getblocktemplate '{"rules": ["segwit"]}' | grep target
"target": "0000000000000000000a2a040000000000000000000000000000000000000000",
bitcoin-cli getdifficulty
เช่นเดียวกัน คุณสามารถถามค่าความยาก (difficulty) ปัจจุบันได้ ซึ่งจากนั้นคุณก็จะสามารถแปลงมันเป็นเป้าหมาย (Target)
$ bitcoin-cli getdifficulty
27692567959234
bitcoin-cli getblockheader
อีกทางหนึ่ง ตามที่ได้กล่าวไป เป้าหมาย (Target) ในตอนที่ดำเนินการขุดจะถูกเก็บในทุกๆ หัวบล็อก (block header) ในรูปแบบของ Bits (ซึ่งคุณสามารถแปลงมันเป็นค่าเป้าหมายแบบเต็มได้)
$ bitcoin-cli getblockheader 000000000000000002e9533a4fe03bb251b3fdb30ffaa384aad133b7fae594cf
{
"hash": "000000000000000002e9533a4fe03bb251b3fdb30ffaa384aad133b7fae594cf",
"confirmations": 207763,
"height": 401184,
"version": 4,
"versionHex": "00000004",
"merkleroot": "b4afa0502a55fdfa4a5cda6ea2bc546ba527d276ea9c7e848b8cd478cd9b6607",
"time": 1457133956,
"mediantime": 1457132303,
"nonce": 3778923481,
"bits": "1806f0a8",
"difficulty": 158427203767.3917,
"chainwork": "00000000000000000000000000000000000000000012da32364c8f47d519604d",
"nTx": 845,
"previousblockhash": "000000000000000003c4a4d9c62b3a7f4893afe14eef8a6a377229d23ad4b1ea",
"nextblockhash": "00000000000000000037ab74c8db9b7a9d7de039210d8eafaeb44ba35adfb624"
}
Code
นี้คือตัวอย่างบางส่วนของ Ruby Code สำหรับการคำนวณค่าเป้าหมาย (target) ใหม่ Code นี้จะทำงานกับเป้าหมาย (target) ใหม่สำหรับบล็อก 403,200 ใช้บันทึกเวลาจากสำหรับบล็อก 401,184 และ 403,199.
Ruby
# 403,200 - NEW TARGET
# 403,199 | last block
# |
# |
# |
# 401,184 - NEW TARGET | first block (target = 0x000000000000000006f0a8000000000000000000000000000000000000000000)
# 1. Get the timestamps for the first and last block in the target adjustment period
first = 1457133956 # block 401,184
last = 1458291885 # block 403,199
# 2. Work out the ratio of the actual time against the expected time
actual = last - first # 1157929 (number of seconds between first and last block)
expected = 2016 * 10 * 60 # 1209600 (number of seconds expected between 2016 blocks)
ratio = actual.to_f / expected.to_f
# 3. Limit the adjustment by a factor of 4 (to prevent massive changes from one target to the next)
ratio = 0.25 if ratio < 0.25
ratio = 4 if ratio > 4
# 4. Multiply the current target by this ratio to get the new target
current_target = 0x000000000000000006f0a8000000000000000000000000000000000000000000
new_target = (current_target * ratio)
# 5. Don't let the target go above the maximum target
max_target = 0x00000000ffff0000000000000000000000000000000000000000000000000000
new_target = max_target if new_target > max_target
# 5. Truncate the target, because the official target is the truncated "bits" format stored in the block header
# This code is a bit rough, because it's working with strings when I should really be working with actual bytes.
new_target = new_target.to_i.to_s(16) # convert from decimal to hexadecimal
new_target = new_target.size % 2 != 0 ? '0' + new_target : new_target # make sure it's an even number of characters (i.e. bytes)
truncated = new_target.scan(/../).each_with_index.map { |byte, i| byte = i >= 3 ? "00" : byte }.join # set all bytes apart from first 3 to zeros
# e.g. 6a4c316c01f354000000000000000000000000000000000 <- full precision
# e.g. 6a4c3000000000000000000000000000000000000000000 <- official target
# 6. Display the full target (with leading zeros)
target = truncated.rjust(64, '0')
puts target
# 000000000000000006a4c3000000000000000000000000000000000000000000