DEV Community

gamer
gamer

Posted on • Updated on

Formance from 0 to 0.5

What?
Formance Stack เป็น open-source tool ที่ออกแบบมาเพื่อที่จะช่วย developer สร้าง, จัดการ, และติดตามการเข้าออกของเงินในบัญชี โดยเราสามารถนำ tool นี้มีใช้ได้ในโปรเจ็คขนาดเล็ก หรือแม้กระทั่งใน platform ทางการเงินขนาดใหญ่

Formance Ledger?
Formance Ledger คือ service ที่ทำให้เราสามารถติดตามการเคลื่อนไหวหรือ สถานะเกี่ยวกับการเงินได้แบบ real-time และเราสามารถ disign และบันทึก transaction ทางการเงินที่มีความสับซ้อนได้อีกด้วย ซึ่งเราสามารถเขียนโปรแกรมสั่งการได้โดยใช้ Numscript ที่ทำหน้าที่เป็น DSL (domain-specific language) ที่ถูกออกแบบมาช่วยเรา model transaction ทางการเงิน

Hello Formance!!!
มาลองใช้ง่ายแบบง่ายๆเพื่อให้เห็นภาพมากขึ้น Formance ได้จัดเตรียมวิธี install service ไว้หลายวิธีแต่วิธีที่ผมเลือกจะใช้ Docker

docker run -p 3068:3068 \
-v $HOME/numary:/root/.numary \
--env NUMARY_SERVER_HTTP_BIND_ADDRESS="0.0.0.0:3068" \
ghcr.io/formancehq/ledger:latest
Enter fullscreen mode Exit fullscreen mode

หรือ Docker compose ซึ่งจะมาพร้อมกับ service postgres ซึ่งเป็น database ที่ใช้แทน default ที่เป็น sqlite

curl -L https://raw.githubusercontent.com/formancehq/ledger/main/docker-compose.yml -o docker-compose.yml

docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

ทดสอบโดยการใช้คำสั่ง

curl -X GET http://127.0.0.1:3068/_info

Hello world!!!
ในหัวนี้เราจะเรียนรู้:

  • การสร้าง Formance Ledger
  • สร้าง models transaction และ account โดยใช้ Numscript
  • นำเงินเข้าสู่ระบบด้วย @world account
  • ตรวจสอบ transaction และ ยอดคงเหลือใน account

อธิบาย @world account เพิ่มเติมที่ต้องมี account นี้เนื่องจากตัว Formance ledger มีการกำหนดว่าเงินที่เข้ามาในระบบไม่สามารถเสกมาจากอากาศลอยๆได้ ดังนั้นจึงต้องมี @world account เพื่อใช้นำเงินจากภายนอกเข้ามาสู่ในระบบ ledger ของเรา

จากหัวข้อด้านบนตอนนี้เราจะมี service Ledger รันอยู่ในเครื่องแล้ว เราลองมาสร้าง transaction แรกกันด้วยการสร้าง Numscript

first.num

send [COIN 100] (
  source = @world
  destination = @centralbank
)
Enter fullscreen mode Exit fullscreen mode
jq -Rs '{plain: .}' first.num \
| curl -H "Content-Type: application/json" \
-X POST --data-binary @- \
https://localhost/api/ledger/{default}/script
Enter fullscreen mode Exit fullscreen mode

Checking balances
ตรวจสอบรายการสามารถทำได้ด้วยการส่งคำสั่ง

curl --location --request GET 'http://localhost/api/ledger/{quickstart}/aggregate/balances?address=centralbank'
Enter fullscreen mode Exit fullscreen mode

Storage consideration
ตัว Formance เองรองรับการเก็บข้อมูลไว้ใน storage 2 อย่างคือ Sqlite และ Postgres ซึ่งโดย default แล้วตัวระบบจะเลือกใช้ Sqlite มาให้ซึ่งสะดวกและง่ายสำหรับการทำการทดสอบบน local แต่ทางระบบเองก็มีการเตือนว่าไม่เหมาะสำหรับการนำมาใช้บน production product และกำลังจะถูก deprecated ใน Formance version 2.X
ตัวเลือกเดียวที่เหมาะสมก็จะเหลือแค่ Postgres ซึ่งเราสามารถใช้งานได้ด้วยการคำหนดค่า Environment

NUMARY_STORAGE_DRIVER=postgres \
NUMARY_STORAGE_POSTGRES_CONN_STRING=postgresql://localhost/dbname \
Enter fullscreen mode Exit fullscreen mode

Concurrency Model
Formance มีการออกแบบการควบคุม concurrency ของ transaction เพื่อป้องกันการเกิด race condition เป็น 2 ส่วนคือ

  • Pre-commit in-memory or Redis-based locking
  • Optimistic locking

ส่วนการเลือกระหว่าง in-memory or Redis นั่นพิจารณาจากว่าหากเรา deploy แบบ multi-instances ให้เลือกใช้ Redis
อ่านเพิ่มเติม

Ledger separation
การเลือกแบ่ง Ledger ใน Formance หรือพูดง่ายๆว่าการแบ่ง schema ของ postgres ว่าเราควรจะทำเป็น single ledger หรือ multi-ledger นั่นมีหลักการตัดสิน 2 ข้อคือ

  • หาก application ของเราไม่มีความจำเป็นต้องแชร์ข้อมูลข้าม ledger กันสามารถทำ multi-ledger ได้
  • application ที่มี workload ด้าน write สูงและสามารถเก็บข้อมูลแยกกันได้สามารถพิจารณาทำ multi-ledger ได้

เพิ่มเติม

Account
เป็นเสมือน container สำหรับ assets เราสามารถส่งและรับ assets ได้ผ่าน transaction โดยผลรวมของ account จะเท่ากับ

balance(account)=∑postings(destination)−∑postings(source)

การตั้งชื่อ account มีการกำหนดว่าต้องตาม เงื่อนไขดังนี้
^[a-zA-Z_0-9]+(:[a-zA-Z_0-9]+){0,}$
และแนะนำให้ใช้เครื่องหมาย colon ให้การแบ่ง structure เช่น
payments:001:authorizations:001
sales:001:contract

นอกจากนั้นใน account เรายังสามารถเพิ่มตัว metadata เข้าไปได้ด้วยเพื่อใช้อธิบายรายละเอียดเพิ่มเติมของ account นั่นๆ
เพิ่มเติม

Posting
คือการเคลื่อนที่ของจำนวนของ asset จาก account นึงไปยังอีก account นึง เช่น Alice ให้ 100 coins ไปที่ Bob

{
  "source": "alice",
  "destination": "bob",
  "asset": "COIN",
  "amount": 100
}
Enter fullscreen mode Exit fullscreen mode

Transaction
ใน Formance transaction คือการ model การรวมกันของ posting ซึ่งเจตนาคือต้องการต้องการทำให้เป็น atomically ตัวอย่างเช่น Alice ใช้ coin ซื้อ gem ผ่าน counter

{
  "postings": [
    {
      "source": "alice",
      "destination": "teller",
      "amount": 100,
      "asset": "COIN"
    },
    {
      "source": "teller",
      "destination": "alice",
      "amount": 5,
      "asset": "GEM"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

เพิ่มเติม

Architecture
architecture
Control dashborad
control dashborad
https://control.formance.com/

Mastering Numscript
coming soon
numscript template

Top comments (0)