Blockchain EP.2 : Make a Transactions

Anonymous
Nextzy
Published in
4 min readApr 17, 2018

จากตอนที่แล้ว เราเริ่ม Implement ตัว Blockchain อย่างง่ายเพื่อบันทึกข้อความเฉยๆ ในตอนนี้เราจะมาทำความเข้าใจและเริ่มทำ Transaction ในระบบ Blockchain กันนะครับ

ตอนที่แล้วเราใช้ Text แทนใส่ส่วนของ Data ของ Block กัน แต่ในระบบ Blockchain จริงๆนั้น ข้อมูลที่ถูกเก็บในส่วนของ Data นั้นจะเก็บ Transactions ที่เกิดขึ้นแทน โดย Transactions นั้นเป็นข้อมูลการโอนเงินระหว่างที่หนึ่งไปยังอีกที่หนึ่ง เช่น A โอนให้ B 5 BTC หรือ B โอนให้ C 2 BTC เป็นต้น

What is Transaction in Blockchain?

Transaction คือการเก็บการโยกย้ายค่าจากเจ้าของคนหนึ่งไปยังเจ้าของคนหนึ่งในระบบ Blockchain เช่น การโอนเงินจาก A ไป B เป็นจำนวนเงินเท่าไหร่ โดยในแต่ละ Transaction จะบันทึก Input คือค่าของเจ้าของคนเดิมที่จะนำมาใช้จาก Transaction ก่อนหน้านี้ที่ยังไม่ผ่านการใช้งาน และบันทึกผลลัพธ์ลงเป็น Output ของ Transaction ว่า โอนให้ใครไปเท่าไหร่ และเหลือทอนมาให้ตัวเองเท่าไหร่

  • A จะมีเงินในระบบได้ก็ต่อเมื่อมีคนโอนให้ A เท่านั้น เมื่อมีคนโอนให้ A ก็จะเกิด Transaction ของ A ในระบบ
  • เงินก้อนแรกออกมาจาก Genesis Block เป็นตัวกำหนดเงินตั้งต้นของระบบ โอนให้กับคนแรกที่สร้าง Genesis Block ซึ่งโดยปกติคือคนสร้างระบบนั่นแหละ
  • เงินที่ A จะสามารถนำไปใช้สร้าง Transaction ได้ สามารถดึง Output จาก Transaction ก่อนหน้านี้ที่ A รับมาและยังไม่เคยถูกดึงไปใช้เท่านั้น และสามารถดึงไปเท่าที่จะใช้ก็ได้ เช่น A เคยรับมา 3 Trxn เป็นจำนวนเงิน 3 / 4 / 4 BTC ตามลำดับ A จะโอนเงิน 5 BTC ก็ดึงแค่ 2 Trxn แรกมาคำนวนสำหรับ Transactions ใหม่ได้เลย
  • A จำเป็นต้องมีเงินในระบบมากพอที่จะทำรายการได้ (ก็แหงละ)

ยอดเงินใน Output ของ Transaction ล่าสุด ไม่ใช่จำนวนเงินทั้งหมดที่มีอยู่ของ A แต่การหายอดเงินที่ A มีอยู่ จะต้องทำการค้นหาในทุกๆ Block ทุกๆ Transaction ที่ A เคยรับมาและ A ยังไม่ได้ใช้ไปมารวมกัน

จากตัวอย่าง A โอนให้ B จำนวน 5 BTC เราก็เริ่มจาก

  • ดึง Transaction Output ที่ A เคยรับเงินมา ให้มากพอที่จะทำรายการใหม่ (เกิน 5 BTC) จากตัวอย่างคือดึงมา 2 Trxn จำนวน 7 BTC
  • นำ Output เหล่านั้นไปเป็น Input ของ Trxn ใหม่
  • คำนวน Output ของ Transaction ใหม่ โดย A ก็จะโดนโอนออกไป 5 เหลืออยู่ 2 BTC และ B ก็ได้รับ 5 BTC จากนั้นก็บันทึกลงใน Output ของ Transaction
  • ฺTx10108 / Tx10210 Output ของ A ก็จะถูกระบุว่าใช้ไปแล้ว ไม่สามารถนำมาใช้ได้อีก หาก A จะทำ Transaction ใหม่อีกรอบ ก็ต้องนำ Transactions อื่นๆที่ยังไม่ถูกใช้งานมาใช้นะครับ เช่น ดึงจาก Tx10023 หรือ Tx10510 อันใหม่ของเรา

ดังนั้น 1 Output ที่ได้รับมา เราจะสามารถนำมันไปใช้สร้างรายการได้แค่ Transaction เดียวเท่านั้น ให้มองว่าเรามีแบงค์ 1000 ใบเดียว เราไม่สามารถนำแบงค์ไปซื้อของ 2 ร้านพร้อมกันได้นั่นเอง

CoinBase Transaction

แน่นอนว่าผู้ใช้ไม่ได้มีเงินในระบบมาตั้งแต่แรกอยู่แล้ว แล้ว Transactions ที่เกิดขึ้นเราจะเอา Input มาจากที่ไหนมาใส่ละ จึงมีบาง Transaction ที่ระบบยินยอมให้ไม่จำเป็นต้องมี Input ของ Transaction ก็ได้ หรือเป็น Transaction ที่ระบบเป็นคนส่งเงินให้เรา ไม่ใช่ผู้ใช้คนอื่นส่งมา เราเรียกรายการรูปแบบนี้ว่า CoinBase Transaction ซึ่งจะมีใช้กันหลักๆอยู่ 2 อย่างคือ

  • Genesis Block Transaction
    แน่นอนว่าผู้ใช้กลุ่มแรก ระบบย่อมเป็นคนส่งเงินให้อยู่แล้ว โดยใช้ Coinbase Transaction โอนให้ และยังเป็นการกำหนดยอดเงินในระบบตั้งต้นตั้งแต่แรกด้วยนั่นเอง
  • Mining Reward Transaction
    Reward ที่ส่งให้สำหรับคนที่เข้ามาช่วยยืนยัน Transaction นี้ไปได้ (หรือมาขุด) ตัวระบบจะเป็นคนส่งให้ด้วย Coinbase Transaction นั่นเอง เช่น ตัว Bitcoin ในทุก Block จะต้องมี Coinbase Transaction เสมอเพื่อเป็น Reward ให้คนขุด โดยระบบก็ออกแบบให้ Reward นั้นลดลง 2 เท่า ทุกๆ 210,000 Block เพื่อป้องกันเงินเฟ้อในระบบนั่นเอง

ใน Bitcoin นั้น รายได้ของนักขุดนอกจาก Reward จากการขุดแล้ว ยังมีค่า Transaction Fee ที่คนที่ทำรายการนั้นส่งมาให้ โดยไม่มีค่าตายตัว จึงทำให้เห็นบางช่วงที่มีการทำรายการในระบบบิตคอยสูงมากนั้น Transaction ที่ต้องการได้รับการยืนยันจึงที่รวดเร็วจึงต้องจ่ายค่า Fee สูง เพื่อให้นักขุดเลือกรายการนั้นเข้าระบบให้เร็วที่สุดนั่นเอง (ทุนนิยมที่แท้ทรู )

Let’s Coding

ต่อจากบทความตอนที่ 1 เลยนะครับ ใครยังไม่เริ่มแนะนำให้กลับไปดูก่อนนะครับ จะไม่ได้เพราะ เพราะในบทความนี้เราจะดัดแปลงโค้ดจากตอนที่แล้วเพื่อเอาระบบ Transaction เข้าไปไว้ในระบบ Blockchain ที่มีอยู่แล้ว และในส่วนของ Cmd เพิ่มเติมสามารถดูได้จาก Gist เลยครับ

Transaction Structure

ตัว Transaction ก็จะเก็บข้อมูลหลักๆอยู่ 3 ตัวคือ id , vin ( output จากรายการก่อนๆ ) และ vout ( ผลลัพธ์ของรายการ )

Create Transaction

จากนั้นสร้างฟังก์ชันสำหรับสร้างรายการใหม่ โดยเราค่า คนส่ง คนรับ และยอดเงิน โดยทำการหา Transaction เก่าๆที่ยังไม่ได้ใช้เพื่อดึงยอดเงินที่สามารถใช้ได้ และนำมาสร้างเป็นรายการถัดไป หากยอดเงินไม่เพียงพอก็สามารถตัดจบการทำงานไปได้เลย

Traverse Transactions though Blockchain

ในขั้นตอนการโอนเงินนั้น เราจำเป็นต้องตรวจสอบด้วยว่าบัญชีที่จะทำการโอนนั้น มียอดเงินเพียงพอให้โอนรึเปล่า โดยการค้นหาทุกๆรายการในทุก Block ที่บัญชีนั้นเคยรับมาและยังไม่ได้ใช้ไปนะครับ

  1. ดึง Pending Transaction มาเก็บไว้ว่าใช้ไปแล้ว
  2. วนลูป Iterator จาก Block ล่าสุดไปยัง Genesis Block
  3. เก็บค่า Input จาก Transaction ของ A ที่เคยใช้ไป เป็นชุดข้อมูลไว้เปรียบเทียบว่า Transaction นี้เคยใช้ไปแล้ว
  4. นำค่า Output มาเช็คกับข้อ 2 หากไม่พบ แสดงว่า Output นี้ยังไม่ได้ถูกใช้ไป สามารถนำไปใช้ได้
  5. ค้นหา Transactions ไปเรื่อยๆ จนกว่าจะได้ยอดรวมที่เพียงพอที่จะเอาไปโอนได้ ( ไม่จำเป็นต้องหายอดรวมทั้งหมด )

ขั้นตอนการสร้าง Transaction เราก็เช็คค่า Balance ที่เราดึงมาได้จาก findUnusedTransaction ว่าเพียงพอต่อการโอนหรือไม่ หากไม่เพียงพอก็จบการทำงานไปได้เลย

Create Coinbase Transaction

ใน Transaction ที่เป็น coinbase นั้น จะมี Input อยู่แค่ตัวเดียว ซึ่งเป็น Input เปล่าจากระบบ (ใส่อะไรก็ได้ ) ดังนั้นเราจึงได้เป็นรายการใหม่ได้เลยจาก Address ของผู้รับและยอดเงิน

Transaction in Blockchain

จากนั้นเราจะทำการแก้ไขตัว Block ของเราจากที่เคยเก็บ Data เป็นแค่ Text ให้มาเป็น Transactions Array กันครับ โดยเปลี่ยนแปลงโครงสร้างและฟังก์ชันเล็กน้อย

และใน Blockchain ก็เพิ่ม DB สำหรับเก็บ Transactions ที่สร้างเข้ามาและรอการนำไปสร้างเป็น Block เพิ่มเข้าไป และเพิ่มฟังก์ชันสำหรับดึงและบันทึกลง DB

Get Balance

เราสามารถใช้ฟังก์ชัน findUnusedTransaction จากขั้นตอนที่แล้วได้เลย โดยให้วนหาในทุกๆ Block โดยไม่ต้องหยุดนั่นเอง เราก็จะได้ผลรวมของยอดเงินที่สามารถใช้ได้ของ Account นั้น

Command Line Interface

ปรับ CLI ของเราให้รองรับการรับค่า Address สำหรับคำสั่งต่างๆ ดูโค้ดเต็มๆได้ที่นี่ >> Gist

Testing

เริ่มจากทำการสร้าง Blockchain ใหม่ โดยกำหนด Address ที่จะให้เราเงิน Coinbase เขาเราก่อน โดยใช้คำสั่ง init ในที่นี้ผมส่งให้ A ละกัน

ลองตรวจสอบ Balance ของ A ก็จะมี 1000 Coin จาก Coinbase ที่โอนให้ใน Genesis Block นะครับ

จากนั้นมาลองคำสั่งโอนกัน โอนให้ B สัก 18 coin แล้วสั่ง mine ให้ทำการสร้าง Block ใหม่

ลอง Check Balance ของทั้งสองดูก็จะยอดเงินที่เหลือ

ลองโอนจาก B ไปให้ C ด้วยยอดเงินที่มากกว่า 18 ก็จะพบว่าไม่สามารถทำรายการได้

References

--

--