Published on
Terra

บันทึกการใช้งาน Terrain และ LocalTerra สำหรับทำ Smart Contract บน Terra

use-terrain-with-localterra

สวัสดีครับ วันนี้ขอบันทึกเกี่ยวกับการใช้งาน Terrain และ LocalTerra ครั้งแรกนะครับ ส่วนตัวผมไม่เคยเขียนหรือทำอะไรกับ Platform ทางฝั่ง Terra เลย เคยได้ยิน และเห็นบทความผ่านตามาเฉยๆ (มีก็แค่ใช้ Terra Station ครับ แต่ในฝั่ง Developer คือ ประสบการณ์ 0)

ทำไมถึงเลือก Terra? จริงๆ ต้องบอกว่า ผมไม่ได้เลือก แต่ว่าอยากลองหลายๆ Protocol ที่ใช้ Rust ในการพัฒนา Smart Contract ครับ รวมถึง Solana, NEAR, Polkadot, Mina พวกนั้นด้วย วันนี้ก็เลยลอง Terra ซะหน่อย (เหลือแค่ Mina ที่ยังไม่เคยลองจริงๆ แค่อ่านผ่านๆครับ)

  • LocalTerra - เป็นตัว Terra testnet บน Local (ใช้ docker)
  • Terrain - น่าจะเปรียบเสมือน Hardhat ของฝั่ง EVM-based

Install Rust

หากไม่เคยติดตั้ง Rust ก็ต้องติดตั้ง Rust ก่อน แนะนำติดตั้งผ่าน rustup

rustup default stable
rustup target add wasm32-unknown-unknown

ลองเช็ค target list กับ version:

rustup target list --installed
cargo version

Setup LocalTerra

ถ้าหากต้องการทำ dApp ก็ต้องใช้ LocalTerra เพื่อเป็น local server, แต่จริงๆ ก็ใช้ testnet ได้เหมือนกับ ถ้าไม่ต้องการความยุ่งยากในการติดตั้ง (และผมก็คิดว่าต่อไป อาจจะใช้ testnet ดีกว่า)

  • ต้องติดตั้ง Docker (เพราะเราจะ setup ผ่าน docker)
  • Docker ตั้ง RAM ไว้เลย 4GB ขึ้นไป (ผมตั้งไว้ 8GB) ลองน้อยๆ รันได้ แต่ compile contract ไม่ผ่าน
  • Node LTS v16 ขึ้นไป

ดาวน์โหลด LocalTerra จาก Github

git clone --branch v0.5.2 --depth 1 https://github.com/terra-money/localterra

Start localTerra ด้วย docker-compose

cd localterra
docker-compose up

Terrain

ตัว Terrain เป็นเหมือน scaffold app / starter / boilerplate ที่มีตัว Contract และ Setup ไว้ให้เราแล้ว มีทั้ง contarcts, frontend, lib

npx terrain new my-terra-dapp

โดยตัว scaffold จะให้โปรแกรม contract counter มา

.
├── contracts              # contracts' source code
│   ├── counter
│   └── ...                # more contract can be added here
├── frontend               # frontend application
├── lib                    # predefined functions for task and console
├── tasks                  # predefined tasks
├── keys.terrain.js        # keys for signing transacitons
├── config.terrain.json    # config for connections and contract deployments
└── refs.terrain.json      # deployed code and contract referecnes

สิ่งที่ผมทำคือ ลองอ่าน contracts อ่าน frontend และ lib ควบคู่ไปกับ Doc เพิ่มเติม ว่ามันทำงานยังไง สิ่งที่เห็นหลักคือ

  1. instantiate - เป็น entrypoint ของโปรแกรม กำหนด initial state ต่างๆ
  2. execute() เอาไว้สำหรับ เปลี่ยนค่า state ข้างในมี matching increment กับ reset
  3. query() - สำหรับการ read data จาก state.

เมื่อดู function ใน contracts กับไฟล์ lib/index.js แล้วเปรียบเทียบการ interact ก็จะเห็นภาพมากขึ้น

Deploy contract

วิธีการ deploy ก็คือ คำสั่งนี้ (โดยปกติถ้าไม่ได้กำหนด option network ตัว default คือ localterra)

npx terrain deploy counter --signer test1
  • ตัว test คือ signer ที่ถูกตั้งค่ามาให้แล้ว เป็น account test ที่มีทั้ง address และ mnemonic (ห้ามเอาไปใช้ production) - LocalTerra Accounts
  • ขั้นตอน deploy นี้แหละ ถ้า Docker เรามี RAM น้อย จะ compile และ deploy ไม่ผ่าน (ผมติดตรงนี้นานมากๆ build ที 4-5นาที) สุดท้าย ต้องเพิ่ม RAM Docker เป็น 8GB ถึงจะ compile และ deploy ผ่าน

หรือสามารถ deploy โดยระบุ signer จากไฟล์ config.terrain.json ก็ได้ เช่น

npx terrain deploy counter --signer custom_tester_1

Terrain console

เราสามารถใช้ terrain console เพื่อ interact กับ contract ที่เรา deploy ไปแล้วได้

npx terrain console

เช่น เรียก method increment()

await lib.increment();
  • method นี้มาจากไหน? เราต้องไปดูไฟล์ lib/index.js
lib/index.js
module.exports = ({ wallets, refs, config, client }) => ({
  getCount: () => client.query("counter", { get_count: {} }),
  increment: (signer = wallets.validator) =>
    client.execute(signer, "counter", { increment: {} }),
});

สิ่งที่ terrain console ทำ คือมันจะมาเรียก function ที่เรากำหนดไว้ เช่น increment() มันก็ไปเรียก client.excute() และถ้าเราเรียก getCount() มันก็จะไปเรียก client.query() ซึ่ง

Terrain tasks

ตัว Tasks หรือเราต้องการรัน script ง่ายๆ ก็สามารถสร้างไว้ในโฟลเดอร์ tasks ได้ ดูตามตัวอย่าง scaffold และ เวลารัน ก็แค่พิมพ์ชื่อ task หรือ file:

Frontend

ตัว Frontend ก็เป็น dApp ธรรมดา ที่กดเพิ่ม counter แต่ว่าต้องต่อกับ Wallet โดยใช้ Terra Station Browser Extension ครับ

terrain sync-refs

จะเป็นการ copy ตัว contract address ที่เรา deploy ไป ให้มันอัพเดทที่ตัว frontend ด้วย (ไม่ต้องมา copy ด้วยมือ)

cd frontend
npm install
npm start

ส่วนนี้ก็ไม่มีอะไรมากเป็น React ด้วย Create React App

npx terrain task:run example-with-lib

Learn Terra

สิ่งที่จะทำต่อจากนี้คือ ลองเรียนหรือตาม Tutorial ต่างๆ ณ​ ตอนนี้ที่เห็นหลักๆ ก็จะมี

สรุป

หลังจากลองตั้งค่า ลองเล่น scaffold ไป ส่วนตัวแล้วรู้สึกว่า ตัว Smart Contract อ่านยากกว่าทางฝั่ง Solana หรือ NEAR นิดหน่อย ส่วนนึงอาจเพราะ Terra นั้นใหม่ สำหรับผม (เพิ่งลองวันนี้) แต่ก็มีความสะดวกของ scaffold ที่มี console และ task ที่ทำให้เราสามารถรัน script ง่ายๆ เหมือนใช้ Hardhat เลย แล้วเดี๋ยวถ้ามีโอกาสได้ลองเล่น ลองใช้งานมากขึ้น จะเอามาเขียนบล็อกอัพเดทอีกทีนะครับ

Happy Coding ❤️

References

Authors
Discord