สรุป session สาย blockchain แบบมัดรวม จากงาน Dev Mountain Tech Festival
งาน Dev Mountain Tech Festival เขามี speaker ที่เรียกได้ว่าชั้นนำของวงการเนอะ แล้วก็มีหลายๆ session น่าสนใจ เราก็เลยเลือกไปฟังฝั่ง Blockchain ว่ามีอะไรบ้างเนอะ ก็เลยสรุปมาในบล็อกนี้
ซึ่งงาน Dev Mountain Tech Festival จัดขึ้นวันที่ 18-19 มีนาคม 2565 ที่ Toscana Valley โคราช แต่ทีมออนไลน์ก็มาฟังได้เช่นกันเนอะ
บล็อกนี้ขอสรุป session สาย Blockchain แบบรัวๆ ว่ามีอะไรบ้างเนอะ บางอันอาจจะมึนๆนิดนึงเนอะ พยายามเขียนให้เข้าใจง่ายที่สุด ขออภัย ณ ตรงนี้เลยแล้วกัน
ปล. เราไม่ใช่ Blockchain Developer นะ
Hacking The (Smart) Contract
speaker ท่านนี้เป็น Security Audit ฝั่ง Blockchain โดยใน session นี้มี agenda ตามหัวข้อดังนี้
Background and Experience
ที่ Valix จะทำการ audit เกี่ยวกับ blockchain product ต่างๆ อย่างของ GameFi ที่ทำ on-chain แต่เกิดการแฮกที่ off-chain เขาก็ทำ pentest ให้
อันนี้ลูกค้าเขา
เคสที่ทำแล้วนำมาเสนอใน session น้ี
- Biswap : หาช่องโหว่ critical case เจอแล้ว report กลับไปให้เขา แล้วเขาก็ทำ patch security เพิ่ม
- SushiSwap : ตัว code base ของ SushiSwap ถูกนำมาใช้ในใน yield farming เกือบทุกตัว เจอช่องโหว่ในการ vote proposal ที่ใช้ $SUSHI ทำให้ควบคุมสิทธิ์ในการผ่าน proposal ต่างๆได้ แก้โดยการเปลี่ยนการโหวตเป็น off-chain แทน
Working With Us
ที่นี่เปิดรับ auditor เพิ่มเนอะ คุณสมบัติที่เน้นว่าต้องมี คือ Solidity เคยมีประสบการณ์ในด้าน Software Development มาก่อน แล้วก็มีความรู้เกี่ยวกับ cryptocurrency และ blockchain
Learn Smart Contract Security By Hacking
เนื้อหาหลักใน session วันนี้ นั่นคือการ hack ไปด้วยกัน มา audit ร่วมกันใน session โดยการหาช่องโหว่ใน smart contract จากตัวอย่างเหล่านี้กัน
- smart contract นี้ทำหน้าที่รับเงินจากผู้ใช้ โอน ETH เข้าไปในระบบ ด้วย
deposit()
แล้ว record ว่าเราส่ง ETH มา lock ไว้เท่าไหร่ และwithdrawAll()
ถอนออกครั้งเดียวออกทั้งระบบ ส่วนgetBalance()
เป็นการ check balance ที่เราเอาไป lock ในระบบ ส่วนgetUserBalance()
แต่ละคนมี balance เท่าไหร่
ช่องโหว่เราเดาว่าน่าจะอยู่ใน withdrawAll()
มาดูคำตอบกัน
อันนี้เป็นการโจมตีแบบ Reentrancy เกิดที่ withdrawAll()
ตามที่เราคาดเดาไว้ในใจจริงๆด้วย
อันนี้เป็นไฟล์ที่เอาไว้แฮกเนอะ ดู attack()
ฝากเงิน 1 ETH ส่ง ETH ตามจำนวนที่มี ไปเรียกที่ withdrawAll()
ตรง msg.sender.call
จะ return boolean มา แล้ว reset ค่าหลังจากถอน userBalances[msg.sender] = 0;
แล้วเรียก recevie()
เพื่อใช้รับ ETH ที่ได้มา
การทำงาน เป็น reentrant ทำการเรียก withdrawAll()
ไปเรื่อยๆจนกว่าจะหมด
วิธีการแก้ไข สามารถทำได้ 2 วิธี ใช้อย่างเดียวหรือทั้งคู่ก็ได้ แต่จะไม่ได้ 100% นะ
- mutex lock : นำ
noRentrant()
เข้ามาช่วย เป็น simple lock เมื่อถูก lock แล้ว จะเรียกซํ้าไม่ได้ - เปลี่ยน pattern : checks-effects-interactions ตัว effect คือ ตรง reset ค่า balance เป็น 0 ส่วน interactions เป็นการเรียก external
msg.sender.call
ทำให้ทำ attack ไม่ได้
มี demo ให้ดู account แรกฝาก 10 ETH account สองฝาก 5 ETH account สามทำการรันตัว attack โดยฝากแค่ 1 ETH สุดท้ายจะได้มา 16 ETH (ตัวเอง 1 ETH + ของคนอื่น 15 ETH)
- InsecureAirdrop : ระบบนี้ทำการแจก airdrop ให้คนมา claim ได้ รับที่
receiveAirdrop()
เพื่อ mint airdrop มีการ checkcanReceiveAirdrop
ก่อนที่จะ mint ซึ่งจะ mint ให้แค่ครั้งเดียวเท่านั้นneverReceiveAirdrop
ตรง neverReceiveAirdrop
เก็บ mapper ว่า mint ไปหรือยัง
canReceiveAirDrop()
ข้างในจะ check compat ว่าเขามีสิทธิ์ที่จะได้รับ airdrop ไหม โดยการรับ airdrop ได้จะมี 2 condition ก็คือ คน ไปทำ _;
คือไป mint เลยย กับ smart contract ใช้ inline assembly ช่วย check isContract
ข้างในจะมีการ implement function ไว้ดูว่าเจ้า smart contract ตัวนี้มันรองรับ airdrop นี้ในระบบไหมนะ
ได้เวลาเดา คนไปรับ airdrop น่าจะปกติ แต่การใช้ smart contract ไปรับเนี่ย ถ้าเราเขียนเพื่อรองรับแล้วให้มันไป mint มาก็ได้ไหมนะ อ่ะเดี๋ยวไปดูคำตอบว่าตรงกับที่มโนไหมนะ
อันนี้ไฟล์แฮก attracker เขียน smart contract ขึ้นมาตัวนึง เพื่อ by part ตรงนี้ได้
attack ทำการ call receiveAirdrop
และ canReceiveAirdrop
ทำให้เกิด reentrant และ การ execute modifier จะทำงานจากซ้ายไปขวา (ตรงหลัง external แถว receiveAirdrop()
)
การแก้ไข ใช้ noReentrant
สามารถ lock ได้ในระดับนึง แต่ไม่ทั้งหมด กับการสลับที่ modifier เอา canReceiveAirdrop
ไว้นำหน้า receiveAirdrop
ซึ่ง step การ execute สำคัญ เมื่อ execute จะมีการ set receive เป็น true
จบ session ไปแบบมึนๆ ใครที่อ่านแล้วมึนๆลอง CryptoZombies บทแรกหน่วยแรก เพื่อจะได้เก็ทมากขึ้น
คลิปย้อนหลังจ้า
Missing Introduction to Blockchain Development for Software Engineer
introduction เป็นการนำสิ่งใหม่นำมาปรับใช้ แต่โลกของ blockchain นั้นเปลี่ยนแปลงเร็วมาก ทำไมกันนะ?
composable without permission เช่น ข้อจำกัดทางด้านเทคนิคบางอย่างในโลกเดิม ซึ่ง blockchain ทำลายข้อจำกัดนี้โดยสิ้นเชิง เดิมมี API limit ทำให้ใช้งานได้ไม่เต็มที่ และข้อจำกัดทางด้านกฏหมายด้วย ทำให้เกิด sub-ecosystem จากเดิม
blockchain ก็เหมือน data ชนิดหนึ่ง เก็บ copy แล้วอัพเดตไปด้วยกัน ข้อมูลไม่มีวันเปลี่ยนไปหรือถูกโกงข้อมูล ซึ่ง blockchain เหมาะกับ usecase บางอย่างที่โลกเดิมทำไม่ได้
เช่น DeFi (decentralized Finance) ในโลกเดิมนั้นธนาคารทำหน้าที่เป็นตัวกลางระหว่างคนฝากและคนกู้ แล้วธนาคารก็จะกินส่วนแบ่งตรงนี้ไป ดังนั้นพอเป็น DeFi ก็เอา code ลง smart contract ทำหน้าที่แทนธนาคาร [นิยามของ DeFi ที่ได้ยินมาก็คือการเงินไร้ศูนย์กลาง ก็คือตัดธนาคารออกไปนั่นแหละ แฮร่]
แล้วอะไรคือ DeFi หล่ะ?
ในส่วนนี้เขาเล่าประมาณว่าเป็นการ on-top จากของเดิม
- Fiat มูลค่าไม่เปลี่ยนแปลงในเวลาสั้นๆ คนมีความ trust กับมัน → Stable Coin ออกโดยไม่ต้องขอ regulator ก่อน และยังมีความ trust เหมือนเดิม
- Stock Exchange มี pain point ในโลกเดิม เช่น การทำ IPO ที่มีกฏเกณฑ์ต่างๆ ซึ่งต้องใช้เวลาปั้นบริษัทนานมาก ประมาณ 5 - 10 ปี → UniSwap แก้ pain point ตรงนี้ โดยการตัดตลาดหลักทรัพย์ออกไป ทำเหรียญของตัวเอง ผูกกับ Stable Coin อย่างการเพิ่มคู่เหรียญ หรือ LP (Liquidity Provider) ทำให้ร่นเวลาจาก 10 ปี เหลือแค่ 1 เดือน
- Decentralized Exchange อย่าง WardenSwap หา exchange rate ที่ดีที่สุด ใครก็สามารถทำได้โดยการอ่าน code จาก smart contract
ก่อนที่เราจะพัฒนา blockchain นั้น เราเข้าใจไหมว่าเราจะแก้ไขปัญหาอะไร
Blockchain Trilemma
ไม่สามารถมี 3 คุณสมบัตินี้ได้พร้อมกัน คือ Scalability, Security และ Decentralization
ทำความเข้าใจในแต่ละ layer ซึ่งแต่ละ layer จะนิยามต่างกัน
- layer 1 : transaction ถูก settle เช่น BTC เน้น payment, ETH เน้น smart contract
- layer 2 : scaling แก้ปัญหา trilemma ของ layer 1
- layer 3 : protocol เป็นเหรียญจากการทำ smart contract
- layer 4 : ทำการดึง service ของ layer 3 มา applicate รวมเป็น service เดียว
ปล. layer 3 และ layer 4 จะเกี่ยวกับ DApps (Decentralized Application)
อะไรคือส่วนที่ยากที่สุดของการทำ Blockchain Development?
อยู่ที่นิยาม . . .
สำหรับเรื่อง Scalability
- Transactions speed : เวลาที่ transaction ถูก confirm
- Transactions throughput : จำนวน transaction ต่อ 1 block
แล้ว business ต้องการอะไร? ต้องการ real-time transactions หรือรองรับจำนวน transaction ต่อวินาทีได้เยอะ แล้วเราต้องการแก้ pain point ตรงนั้นหรือเปล่า
นิยามของการ Scalability
- เพิ่ม hardware system เมื่อจำนวน user เพิ่ม
- query เพิ่ม resource เพื่อให้ขึ้นได้ดีหรือเปล่า
- web นั้นรองรับ transaction แล้ว scale ระบบได้ไหม
โลกเดิมคือ web 2.0 อนาคตคือ web 3.0
- past : เข้าใจความต้องการของผู้บริโภค เราต้องขยายกำลังการผลิตอีกเท่าไหร่
- present : เข้าใจในรูปแบบของ data หรือ impactible asset เกิดจากการ redefine ใหม่
- future : user เลือก input และ variable เอง ไม่ใช่ platform เป็นคนกำหนด ดังนั้นสร้าง matric หรือ variable เพื่อให้ transparent ให้ user เห็น และทำตามที่เราต้องการ
รายละเอียดอื่นๆ อ่านในรูปสไลด์ได้เลย
สรุป จริงแค่โลกเดิม ส่วน web 3.0 ไม่จริงเสมอไป และ matric สามารถนำมาใช้หรือชี้วัดได้แค่ใน layer นั้นๆ และวัดแล้วอาจจะไม่ตรงกับที่ user ต้องการ
UniSwap : user ต้องการ rate ราคาแลกเปลี่ยนเหรียญ และมี liquidity ซื้อขายแลกเปลี่ยนอย่างเสรี
แก้ปัญหาด้วย model ทางคณิตศาสตร์
XY = K
K คือค่า constant คงที่ ส่วน X และ Y คือ token ค่านึงขึ้น ค่านึงต้องลง เป็นการลบ logic ในโลกเดิม มี trade-off ไม่ใช่การซื้อขายโดยตรง แต่ model ไม่ได้ reject อย่างสมบูรณ์ ทำให้เกิด slippage เป็นกราฟ polynomial
Scalability วัดจากตัวเองไม่ได้ ต้องวัดจาก ecosystem ทั้งหมด เช่น วาฬทำ transaction ค่า gas เท่ากัน (ซึ่งน้อยมากเมื่อเทียบกับ slippage)
สำหรับเรื่อง Decentralization
เปรียบเทียบโลกเดิมกับ hierarchy ต่างๆ
headquarter อยู่ไหน? จะเป็นแบบ permanent address หรือ physical location
ตัดขาไปแล้ว ปลาดาวงอกขาใหม่ได้ แต่แมงมุมงอกขาใหม่ไม่ได้ เลยควบคุมการเดินไม่ได้ เช่น Binance CZ หายไปจะเป็นยังไง ทำงานต่อได้ไหม แล้วถ้า VITALIK หายไป องค์กร Etherium ทำงานต่อได้ไหม
เหตุผลสำหรับการทำ decentralization : Immutability, Fault tolerance , Attack resistance
สำหรับเรื่อง Security
ข้อมูลใน blockchain ไม่ได้เป็นความลับ, propagates ไปทุกๆ layer เมื่อข้ามกันมีความเสี่ยงตรง bridge มันจะเพิ่มความเสี่ยงเป็นสองเท่า ดังนั้นให้ focus ที่ layer ใด layer หนึ่ง และ focus เฉพาะเรื่องที่เราสนใจเท่านั้น เช่น security เลือก on-top จากสิ่งที่คนอื่นทำได้ดีกว่า
สรุป เราจะ trade-off มันได้อย่างไร
deploy แล้วเปลี่ยนแปลงไมได้ → hard folk ผิดไปนิดเดียว แก้ไขกลับไปไม่ได้ เหมือน design จรวด ที่ปล่อยจรวดออกไปแล้วทำอะไรไม่ได้
แบ่งเป็น component emergence หรือ emergency ต้อง trade-off ทั้งหมดอย่างเพียงพอก่อน
ตัวอย่าง UniSwap
ความท้าทาย คือการทำให้สมดุลกัน balance user behavior
คลิปย้อนหลังจ้า
Blockchain Infrastructure
คุณโดมเริ่มทำ infrastructure ให้ JFIN ตอนออก ICO ทำ platform payment ที่แบงค์ชาติไม่ค่อยชอบ
ตัว JPIN จะอยู่บน Ethereum Mainnet แต่ค่า gas แพง มี chain อื่นที่ค่า gas ถูกกว่าไหม? stellar จะมี SIX Network ใช้ เน้นความเร็ว ซึ่งความเร็วน้อยกว่า BSC ในปัจจุบัน อาจจะเน้นอย่างอื่นแทน เช่น transfer เหรียญไปมา
การเติบโตของ Ethereum
เติบโตโดยคนทำ smart contract หรือ DeFi ซึ่งความเร็วไม่ใช่เรื่องสำคัญ ทำในเรื่องที่ถนัด + off-chain คนไม่ใช้ stellar ในวง private ดังนั้นไป EVM (Ethereum Virtual Machine มี Ethereum เป็น base) จะดีกว่า
และเชื่อว่า blockchain จะเป็น network ในองค์กร
RDBMS ไม่ได้เหมาะ เปลือง ไม่คุ้ม จึงหา database เฉพาะทาง เช่น main cast เก็บ key value, mongoDB เก็บ data, Redis เก็บ cache ซึ่ง blockchain จะเป็นในจุดนั้น
Blockchain ถนัด
- การทำ duplicate data : data แก้ไขยาก และ sync กันอย่างรวดเร็ว
- ไม่มี authentication ยกภาระให้ user จัดการ เช่น Web 3.0, user ดูแล public key และ private key เอง
เช่น user เติมเงิน ใช้จ่ายในระบบ, พ่อค้า เงินเข้าเท่าไหร่ และจ่ายไปเท่าไหร่ ร้านได้เท่าไหร่ เติมเข้าไม่ทำ real-time ค่อยเพิ่มใน database
blockchain – เปลี่ยนเป็น token
โครงสร้าง public blockchain มี 2 - 3 layer โดย layer ล่างสุด คือ peer-to-peer คุยกับ node คล้ายๆ bittorrent เป็น protocol layer รับข้อมูลจาก protocol อื่นแล้วเขียนลง local database ซึ่งจะเก็บแบบไหนก็ได้ ไม่จำเป็นต้องเหมือนกัน
geth mode : ใช้ภาษา Go ในการ implement และ sync ข้อมูลมาเสร็จเขียนลงได้หลายแบบ ตามจุดประสงค์ได้ คือ Sync modes --syncmode "<mode>"
นั่นเอง มี 3 แบบคือ Full, Snap, Light
สนใจ archive มากกว่า --gcmode value
full
อ่านมา เขียนลงได้ เก็บ transaction และ data แต่ละคนแยก ส่ง data ไปมาarchive
ใช้เยอะมากกับการ query data บล็อกนั้นมีเงินเท่าไหร่ ใครถือเท่าไหร่ มองเป็น backup role
ทำ lab ให้ดูกัน โดยใช้ Go Etherium
ก่อนอื่นเตรียมเครื่องกันก่อนตามนี้เลย
node
- miner ใช้ confirm ธุรกรรมแบบ PoA (Proof-of-Authentication) เรียกว่า Validator Node คนได้จะเวียนกันไป ทุกคนมีสิทธิ์เหมือนกัน
- boot node ให้ทุกคนหา node กันเจอเร็วขึ้น ว่าใครอยู่ node ไหนบ้าง ให้แต่ละ node ไปคุยกันเอง broadcast หากัน
อื่นๆ
- PoW (Proof-of-Work) หา hash แบ่งกัน confirm ธุรกรรมได้ก่อน จะได้ reward กลับมา เช่น BTC, ETH
- PoS (Proof-of-Stake) ใครมีเงินเยอะจะได้ไป
ต่อมาสร้าง genesis file
chainId
คือ หมายเลข network ว่ามี address อะไร ใช้ทำธุรกรรม ดูใน chainlist ว่าใครใช้เลยอะไรอยู่
- wallet ใช้ signed message → public key & private key
- pre-mine สร้างเหรียญให้กระเป๋าชุดแรก กระจายเป็นค่า gas กลับไป
- โลกของ asynchronous จะต้องเข้าคิว อย่างของ BTC block time สำคัญมาก เราควรเตรียม storage เท่าไหร่ มี block size มากสุดเท่าไหร่ เช่น BSC ทำธุรกรรมทุก 3 วินาที ทำให้สัมพันธ์กับขนาดของ block size ด้วย
จากนั้นเริ่มใส่ config ที่ genesis.json
กัน
chainId
ซํ้าได้ไม่เป็นไรถ้า privateclique
ชื่อ consensus บอกว่า period time ทุกเท่าไหร่ จึงจะสร้างบล็อกใหม่extradata
ใส่ว่าใครเป็นคน mine อันนั้น ถูกยืมมาใช้ใน genesis block ว่าใครเป็นคน mine และเลขกระเป๋า ดูว่าบล็อกสูงใครเป็นคน mine- PoA จะไม่มี reward block คนเขียน data จ่าย gas
alloc
ให้กระเป๋า มีเหรียญเลขตั้งแต่ block 0 - ใช้ hash ของ json บอกว่าเราอยู่วงไหนในปัจจุบัน
จากนั้นมาสร้าง node แรกกัน
- init hash แล้วก็ genesis hash ก่อน
- สร้าง
password.txt
เอาไปใช้ในการ encrypt key
head -1 /dev/urandom | base 64 | md5sum
cat passwork.txt
- สร้าง account ได้ด้วย account new ไว้ relate จะได้ keystore และ public key สำหรับใช้ signed เอาไปใส่ใน
extradata
ให้กระเป๋านี้ทำธุรกรรม - เอากระเป๋าไป unlock parameter ใน go eth – เอา genesis ไปลง database เพราะใช้หลายครั้ง ได้ validator node
- run docker ดู id, port, gas limit → รัน compose + log ซึ่งควรอยู่หลัง firewall, RPC [ประมาณว่า web 3.0 จะเรียกสิ่งนี้ ซึ่งหน้าที่เหมือน API นั่นแหละ]
- ทำ RPC ไม่ต้องมีการ sign เอา init และ join
bootnodes
คือ node ที่ 1- สร้าง node เพิ่ม เปลี่ยน
bootnodes
เพื่อให้เชื่อมกัน แล้วก็ upmode ขึ้นมา จะเป็น node 2 ชี้ node 1 ตรงกันแล้วก็ sync มาทำงาน สามารถใช้งาน network ได้
- สุดท้าย เปิด Metamask ตั้ง config แล้วก็ส่งเงิน มีธุกรรมเข้ามา sign message
สรุป node 1 เป็น validator node ←→ miner ←→ node 2 มี RPC ให้คนเข้ามาเชื่อม
ปล. ยังไม่มีไฟล์สไลด์ของ speaker ในนั้นเอาไป set ตามได้เลย
Programming Bitcoin
security architecture : วิธีการเขียน มี key concept ยังไง ซึ่ง algorithm และ architecture เป็นสิ่งที่สำคัญในการ scale และ secure มาก
security → transaction (web 3.0) เกี่ยวกับ architecture และการ audit สำคัญอยู่
session จะมีส่วนหลักๆ 2 ส่วน ดังนี้
Part#1 - Security
Signing & Verification
- เป็นที่รู้จัก + trust เช่น เรารู้ว่าไทเกอร์ วูดส์ เป็นโปรกอล์ฟที่ประสบความสำเร็จมากๆ ส่วนชายเสื้อนํ้าเงินเป็นใครก็ไม่รู้ เขาอาจจะเก่งกว่าไทเกอร์ก็ได้
- ยิงธนู – เรายิงแม่น → เกิดการ verify และ trust → scale ต่อไปไม่ได้
- ไม่ใช่แค่การเขียนโค้ด และ compile ผ่าน เราจะต้องสร้าง trust ให้กับ algorithm ของเรา
วิธีแก้ไขปัญหา – ยิงธนูเข้าเป้าในเวลาที่กำหนดไว้ หรือ ยิงสนุ๊กเกอร์เลข 8 ที่เหลือลูกสุดท้าย ลงหลุมที่เราวางไว้
1) Ellipic Curve Cryptography : สิ่งที่คูณได้ จะต้องหารได้เช่นกัน และในบางกรณีคูรได้ แต่หารไม่ได้ ก็คือ private key และ public key นั้นเอง ไม่สามารถ hack key ได้ revert กลับมาไม่ได้ เหมือนเป็นเส้นทาง one way เกิดเรื่อง security
- P – public key, e – private key : จะ random, เส้นสีแดงยิงไปที่ไหน ไม่มีใครรู้ มีสิทธิ์เข้าไปในระบบ และเอาไปถูกวิธีในระบบ
- compile ได้ prove ได้ และ stack ของเรา secure จริงไหม
2) Double Hashing : ทำ SHA256 2 รอบ – รูปแปลงเป็นโค้ด
จริงๆแล้ว cryptographic technology เคยผิดกฏหมายมาก่อน พอ internet เปิดเสรี ให้เอา logic นี้มาใช้ได้ และมีการพัฒนาต่อไปเรื่อยๆ
Part#2 - Transactions
transaction components ประกอบด้วย 4 ส่วน คือ version, inputs, outputs และ locktime
เช่น A ติดหนี้ B 800 บาท แล้ว B ก็ติดหนี้ A 1200 บาท มันจะเป็น 2 transactions ซึ่งสามารถรวบเป็น transaction เดียวได้ เป็น B ต้องจ่าย A 400 บาท ทำให้ high speed ขึ้น
UTXO ที่เกิดขึ้น : make sure ทั้งระบบว่า secure, protect variation ของ coin เราจะสร้างระบบให้มี trust ได้อย่างไร? และมี value อะไร?
สุดท้าย
อัพเดต
สไลด์ของ speaker ในแต่ละ session
คลิปย้อนหลังไปตามในช่องนี้ได้น้า
ในส่วนของ session ที่น่าสนใจของเรา บางอันทำโพสไปแล้ว บางอันทำบล็อกไปแล้ว เนื่องจากงานไม่มีสาย mobile development ก็เลยเข้าสาย blockchain เอาแล้วกันเนอะ
session อื่นๆในงาน Dev Mountain Tech Festival
.
.
สรุป session Lifelong Journey as a Software Engineer
สามารถ support ค่ากาแฟเจ้าของบล็อกได้ที่ปุ่มแดงส้มสุดน่ารักที่มุมซ้ายล่าง หรือกดปุ่มตรงนี้ก็ได้จ้า
กด follow Twitter เพื่อได้รับข่าวสารก่อนใคร เช่น สปอย content ใหม่ หรือสรุป content เร็วๆในนี้จ้า
ติดตามข่าวสารและบทความใหม่ๆได้ที่
Subscribe ช่อง YouTube ของเราได้ที่
download แอพอ่านบล็อกใหม่ของเราได้ที่นี่