BTC
ETH
HTX
SOL
BNB
ดูตลาด
简中
繁中
English
日本語
한국어
ภาษาไทย
Tiếng Việt

DAOrayaki: Aptos & Move คำอธิบายเชิงปฏิบัติ

DAOrayaki
特邀专栏作者
2022-09-21 03:19
บทความนี้มีประมาณ 13659 คำ การอ่านทั้งหมดใช้เวลาประมาณ 20 นาที
บทความนี้อธิบายวิธีการใช้งาน aptos cli และ aptos sdk เป็นหลัก
สรุปโดย AI
ขยาย
บทความนี้อธิบายวิธีการใช้งาน aptos cli และ aptos sdk เป็นหลัก

กลุ่มโบนัสการวิจัย DAOrayaki DAO:

ที่อยู่ของทุน: DAOrayaki.eth

ความคืบหน้าการลงคะแนน: DAO Reviewer 3/0 ผ่าน

ประเภทงานวิจัย: Aptos,Layer1

ผู้สร้าง: FF@DoraFactory

บทความนี้อธิบายการทำงานของ aptos cli และ aptos sdk เป็นหลัก

Clone Aptos-core Repo

# Clone the Aptos repo.
git clone 
# cd into aptos-core directory.
cd aptos-core
# Run the scripts/dev_setup.sh Bash script as shown below. This will prepare your developer environment.
./scripts/dev_setup.sh
# Update your current shell environment.
source ~/.cargo/env
# Skip this step if you are not installing an Aptos node.
git checkout --track origin/devnet

เริ่มเครือข่ายท้องถิ่นของ Aptos

Using CLI to Run a Local Testnet | Aptos Docs[1]

  • เริ่มห่วงโซ่ท้องถิ่น

ps: โลคัลเชนและข้อมูลที่เริ่มต้นโดยวิธีนี้จะถูกบันทึกไว้ในโฟลเดอร์ปัจจุบันที่คำสั่งนี้เริ่มทำงาน และมีอยู่ในไฟล์ .aptos/
aptos node run-local-testnet --with-faucet

เริ่มสำเร็จ:

Completed generating configuration:
        Log file: "/Users/greg/.aptos/testnet/validator.log"
        Test dir: "/Users/greg/.aptos/testnet"
        Aptos root key path: "/Users/greg/.aptos/testnet/mint.key"
        Waypoint: 0:74c9d14285ec19e6bd15fbe851007ea8b66efbd772f613c191aa78721cadac25
        ChainId: TESTING
        REST API endpoint: 0.0.0.0:8080
        FullNode network: /ip4/0.0.0.0/tcp/6181
Aptos is running, press ctrl-c to exit
Faucet is running.  Faucet endpoint: 0.0.0.0:8081

หลังจากเริ่มต้นสำเร็จ ระบบจะแสดงที่อยู่ของ API ที่เหลือและ Faucet API ในภายหลัง ข้อมูลทั้งสองส่วนนี้จำเป็นต้องได้รับการกำหนดค่าในสภาพแวดล้อม aptos cli

  • กำหนดค่าสภาพแวดล้อม aptos cli

ในการเข้าถึงและเรียกใช้ห่วงโซ่การทดสอบในเครื่องผ่านบรรทัดคำสั่ง เราจำเป็นต้องกำหนดค่า config สำหรับ aptos cli ตามข้อมูลการปรับใช้ด้านบน

PROFILE=local
aptos init --profile $PROFILE --rest-url  --faucet-url 

ในระหว่างการดำเนินการ เราจะได้ผลลัพธ์ดังต่อไปนี้ เราสามารถเลือกใส่รหัสลับหรือจะสร้างแบบสุ่มก็ได้

Configuring for profile local
Using command line argument for rest URL 
Using command line argument for faucet URL 
Enter your private key as a hex literal (0x...) [Current: None | No input: Generate new key (or keep one if present)]

หลังจากการยืนยัน บัญชีจะถูกสร้างขึ้นและเติมเงินด้วยจำนวนโทเค็นเริ่มต้น

No key given, generating key...
Account 7100C5295ED4F9F39DCC28D309654E291845984518307D3E2FE00AEA5F8CACC1 doesn't exist, creating it and funding it with 10000 coins
Aptos is now set up for account 7100C5295ED4F9F39DCC28D309654E291845984518307D3E2FE00AEA5F8CACC1!  Run `aptos help` for more information about commands
{
  "Result": "Success"
}

จากนี้ไป เราสามารถเรียกใช้งานได้บน local testnet โดยเพิ่ม --profile local ในคำสั่ง

ps: --profile ที่นี่เหมือนกับ kube-config ใน k8s ซึ่งสามารถตั้งค่าสภาพแวดล้อมโปรไฟล์ที่แตกต่างกันและควบคุมเครือข่ายต่างๆ

การกำหนดค่าโปรไฟล์จะตั้งค่าที่อยู่ตัวดำเนินการ node-rest-api และข้อมูล faucet-api

# รายชื่อบัญชีทั้งหมดที่ควบคุมโดย cli
aptos account list
# เติมเงินในบัญชี:
aptos account fund --profile $PROFILE --account $PROFILE
# สร้างบัญชีทรัพยากรใหม่
aptos account create-resource-account --profile $PROFILE --seed 1
#ทำสัญญาย้ายบ้าน
aptos move compile --package-dir hello_blockchain
#ทำตามสัญญา
aptos move publish --package-dir hello_blockchain --named-addresses basecoin= --profile local
#ทวงสัญญา
aptos move run --function-id :::: --profile local
# แสดงรายการข้อมูลโมดูล/ทรัพยากรของบัญชีที่ระบุ
aptos account list --query modules --account 0xa1285adb4b8abedf5faf7a46d260c5844f1f64d59dd9b8869db1543cf5bbadf4 --profile local
aptos account list --query resources --account 0x4200c2b801870f20a709abba80b6edb90a45ecd9b8acce9842b93d597602edcf --profile local
#สัญญาอัพเกรด
aptos move publish --upgrade-policy
    `arbitrary`, `compatible`,`ไม่เปลี่ยนรูป' สอดคล้องกับ 0, 1, 2
0 ไม่ได้ทำการตรวจสอบใด ๆ บังคับให้เปลี่ยนรหัส
1 ตรวจสอบความเข้ากันได้ (ฟังก์ชันสาธารณะเดียวกันไม่สามารถเปลี่ยนเค้าโครงหน่วยความจำของทรัพยากรที่มีอยู่ได้)
2 ข้อห้ามในการอัพเกรด
ทุกครั้งที่เผยแพร่ จะเปรียบเทียบนโยบายในเครือข่ายกับนโยบายของสิ่งพิมพ์นี้ (ค่าเริ่มต้นคือ 1)
อนุญาตให้อัปเกรดสัญญาได้เฉพาะเมื่อนโยบายในครั้งนี้มีขนาดเล็กกว่านโยบายในเครือข่าย

ปรับใช้สัญญาการย้ายอย่างง่าย

module MyCounterAddr::MyCounter {
    use std::signer;
    struct Counter has key, store {
        value:u64,
    }
    public fun init(account: &signer){
        move_to(account, Counter{value:0});
    }
    public fun incr(account: &signer) acquires Counter {
        let counter = borrow_global_mut(signer::address_of(account));
        counter.value = counter.value + 1;
    }
    public entry fun init_counter(account: signer){
        Self::init(&account)
    }
    public entry fun incr_counter(account: signer)  acquires Counter {
        Self::incr(&account)
    }
}

การวิเคราะห์ซอร์สโค้ด MyCounter

โมดูลคือชุดของฟังก์ชันและโครงสร้างแบบแพ็กเกจที่เผยแพร่ภายใต้ที่อยู่เฉพาะ เมื่อใช้สคริปต์ สคริปต์จำเป็นต้องรันด้วยโมดูลที่เผยแพร่หรือไลบรารีมาตรฐาน และไลบรารีมาตรฐานเองก็เป็นกลุ่มของโมดูลที่เผยแพร่ภายใต้แอดเดรส 0x1

โมดูล MyCounterAddr::MyCounter{ } อยู่ภายใต้ที่อยู่ MyCounterAddr (ตรงกับ MyCounterAddr ="0x4200c2b801870f20a709abba80b6edb90a45ecd9b8acce9842b93d597602edcf") เพื่อสร้างโมดูล

ใช้ std::signer คือการใช้โมดูล signer ภายใต้ไลบรารีมาตรฐาน Signer เป็นชนิดดั้งเดิมที่ไม่สามารถคัดลอกได้ คล้ายกับ Resource ซึ่งมีที่อยู่ของผู้ส่งธุรกรรม เหตุผลประการหนึ่งในการแนะนำประเภทผู้ลงนามคือเพื่อให้ชัดเจนว่าฟังก์ชันใดต้องการสิทธิ์ผู้ส่งและฟังก์ชันใดไม่ต้องการ ดังนั้น ฟังก์ชันจึงไม่สามารถหลอกลวงผู้ใช้ให้เข้าถึงทรัพยากรโดยไม่ได้รับอนุญาต สำหรับรายละเอียด โปรดดูที่ซอร์สโค้ด [2]

module std::signer {
    // Borrows the address of the signer
    // Conceptually, you can think of the `signer` as being a struct wrapper arround an
    // address
    // ```
    // struct signer has drop { addr: address }
    // ```
    // `borrow_address` borrows this inner field
    native public fun borrow_address(s: &signer): &address;
    // Copies the address of the signer
    public fun address_of(s: &signer): address {
        *borrow_address(s)
    }
    /// Return true only if `s` is a transaction signer. This is a spec function only available in spec.
    spec native fun is_txn_signer(s: signer): bool;
    /// Return true only if `a` is a transaction signer address. This is a spec function only available in spec.
    spec native fun is_txn_signer_addr(a: address): bool;
}

Struct & Abilities


struct Counter has key, store {
    value:u64,
}

ใช้ struct เพื่อกำหนดโครงสร้างที่เรียกว่า Counter และในขณะเดียวกันก็แก้ไขโดยตัวจำกัด 2 ชนิด ได้แก่ คีย์และสโตร์

ระบบประเภทของ Move นั้นยืดหยุ่น และแต่ละประเภทสามารถกำหนดความสามารถได้สี่อย่าง

กำหนดว่าค่าของประเภทสามารถคัดลอก ทิ้ง และจัดเก็บได้หรือไม่

ตัวระบุความสามารถทั้งสี่ ได้แก่: คัดลอก วาง จัดเก็บ และคีย์

หน้าที่ของพวกเขาคือ:

  • คัดลอก - สามารถคัดลอกค่าได้

  • Drop - สามารถทิ้งค่าได้เมื่อสิ้นสุดขอบเขต

  • คีย์ - ค่าสามารถเข้าถึงได้เป็นคีย์โดย "การดำเนินการจัดเก็บข้อมูลส่วนกลาง"

  • ร้านค้า - สามารถเก็บค่าไว้ในสถานะส่วนกลางได้

แก้ไขด้วยคีย์และจัดเก็บที่นี่ หมายความว่าไม่สามารถคัดลอก ทิ้ง หรือใช้ซ้ำได้ แต่สามารถจัดเก็บและถ่ายโอนได้อย่างปลอดภัย

ไวยากรณ์สำหรับความสามารถ

ความสามารถของประเภทดั้งเดิมและประเภทในตัวนั้นถูกกำหนดไว้แล้วและไม่เปลี่ยนรูป: ค่าของจำนวนเต็ม, เวกเตอร์, ที่อยู่และประเภทบูลีนมีความสามารถคัดลอก, วางและจัดเก็บโดยเนื้อแท้

อย่างไรก็ตาม สามารถเพิ่มความสามารถของโครงสร้างได้ตามไวยากรณ์ต่อไปนี้:

struct NAME has ABILITY [, ABILITY] { [FIELDS] }

ตัวอย่างไลบรารีอย่างง่าย:

module Library {
    // each ability has matching keyword
    // multiple abilities are listed with comma
    struct Book has store, copy, drop {
        year: u64
    }
    // single ability is also possible
    struct Storage has key {
        books: vector
    }
    // this one has no abilities
    struct Empty {}
}

ทรัพยากรคืออะไร

แนวคิดของทรัพยากรได้รับการอธิบายโดยละเอียดในเอกสารทางเทคนิค Move ในขั้นต้น มันถูกนำไปใช้เป็นประเภทโครงสร้างที่เรียกว่า ทรัพยากร นับตั้งแต่เปิดตัวความสามารถ มันถูกนำไปใช้เป็นโครงสร้างที่มีความสามารถสองอย่างคือ คีย์ และ สโตร์ ทรัพยากรสามารถเป็นตัวแทนของสินทรัพย์ดิจิทัลได้อย่างปลอดภัย ไม่สามารถคัดลอกหรือทิ้งหรือใช้ซ้ำไม่ได้ แต่สามารถจัดเก็บและถ่ายโอนได้อย่างปลอดภัย

ความหมายของทรัพยากร

ทรัพยากรเป็นโครงสร้างที่จำกัดด้วยคีย์และความสามารถในการจัดเก็บ:

module M {
    struct T has key, store {
        field: u8
    }
}ขีดจำกัดของทรัพยากร

ในโค้ด ประเภททรัพยากรมีข้อจำกัดที่สำคัญหลายประการ:

  • ทรัพยากรถูกจัดเก็บภายใต้บัญชี ดังนั้นจึงมีอยู่เฉพาะเมื่อมีการกำหนดบัญชีและสามารถเข้าถึงได้ผ่านบัญชีนั้นเท่านั้น

  • บัญชีสามารถเก็บทรัพยากรประเภทใดประเภทหนึ่งได้ครั้งละหนึ่งรายการเท่านั้น

  • ไม่สามารถคัดลอกทรัพยากรได้ สอดคล้องกันเป็นชนิดพิเศษ: ทรัพยากรซึ่งแตกต่างจากที่คัดลอกได้ซึ่งได้รับการแนะนำในบทเกี่ยวกับข้อมูลทั่วไป (สิ่งนี้สามารถสรุปได้ถึงความเป็นเจ้าของของ Rust)

  • ต้องใช้ทรัพยากร ซึ่งหมายความว่าทรัพยากรที่สร้างขึ้นใหม่จะต้องถูกย้ายภายใต้บัญชี และทรัพยากรที่ย้ายจากบัญชีจะต้องแยกส่วนหรือจัดเก็บภายใต้บัญชีอื่น

เรื่องเมื่อกี้

struct Counter has key, store {
    value:u64,
}

ดังนั้นนี่คือความแตกต่างจาก solidity หากจำเป็นต้องออกสินทรัพย์ใหม่บน eth เช่น usdc จากนั้นสินทรัพย์นี้จะถูกบันทึกไว้ในแผนที่ในสัญญา แต่การย้ายนั้นแตกต่างออกไป เนื้อหาจะถูกเก็บไว้ภายใต้ที่อยู่ของผู้ใช้เป็นทรัพยากร

กำหนดฟังก์ชัน

public fun init(account: &signer){
    move_to(account, Counter{value:0});
}
public fun incr(account: &signer) acquires Counter {
    let counter = borrow_global_mut(signer::address_of(account));
    counter.value = counter.value + 1;
}
public entry fun init_counter(account: signer){
    Self::init(&account)
}
public entry fun incr_counter(account: signer)  acquires Counter {
    Self::incr(&account)
}

รูปแบบคำจำกัดความคือ:

ชื่อฟังก์ชัน public fun (พารามิเตอร์: ประเภทพารามิเตอร์) { }

ฟังก์ชันการย้ายเป็นแบบส่วนตัวโดยค่าเริ่มต้น และสามารถเข้าถึงได้ภายในโมดูลที่กำหนดไว้เท่านั้น คำหลักสาธารณะจะเปลี่ยนการเปิดเผยเริ่มต้นของฟังก์ชันและทำให้เป็นสาธารณะ กล่าวคือ สามารถเข้าถึงได้จากภายนอก

พารามิเตอร์ของเมธอด init คือ &signer ซึ่งหมายความว่าเมธอดนี้สามารถเรียกได้หลังจากบัญชีได้รับการเซ็นชื่ออย่างถูกต้องตามกฎหมายเท่านั้น move_to เป็นคำสั่งดั้งเดิมของ move ซึ่งใช้เพื่อเผยแพร่และเพิ่มทรัพยากร Counter ไปยังที่อยู่ของผู้ลงนาม ในรูปแบบบัญชีของ Move รหัสและข้อมูลจะถูกเก็บไว้ภายใต้ที่อยู่บัญชี

ต่อไปนี้เป็นรายการของพื้นฐานที่ใช้กันทั่วไป

  • move_to< T >(&signer,T): เผยแพร่และเพิ่มทรัพยากรประเภท T ไปยังที่อยู่ของผู้ลงนาม

  • move_from< T >(addr: ที่อยู่): T - ลบทรัพยากรประเภท T ออกจากที่อยู่และส่งคืนทรัพยากรนี้

  • borrow_global< T >(addr: ที่อยู่): &T - ส่งกลับการอ้างอิงที่ไม่เปลี่ยนรูปไปยังทรัพยากรประเภท T ที่ที่อยู่

  • borrow_global_mut< T >(addr: ที่อยู่): &mut T - ส่งกลับการอ้างอิงที่ไม่แน่นอนไปยังทรัพยากรประเภท T ที่ที่อยู่

  • exists< T >(ที่อยู่): บูล: กำหนดว่ามีทรัพยากรประเภท T อยู่ใต้ที่อยู่หรือไม่

พารามิเตอร์ของเมธอด incr ยังเป็น &signer ซึ่งหมายความว่าเมธอดต้องได้รับการเซ็นชื่อตามกฎหมายโดยบัญชีก่อนจึงจะสามารถเรียกใช้ได้

คำสำคัญที่ได้รับซึ่งวางไว้หลังค่าส่งคืนของฟังก์ชัน ใช้เพื่อกำหนดทรัพยากรทั้งหมดที่ได้รับจากฟังก์ชันนี้อย่างชัดเจน

ผู้ลงนาม::address_of(บัญชี) รับที่อยู่จากผู้ลงนาม

ดังที่กล่าวไว้ข้างต้น border_global_mut ตัวแปรจะยืมตัวนับทรัพยากรภายใต้ที่อยู่ จากนั้นจึงดำเนินการ +1 กับค่าภายใต้โครงสร้างตัวนับ

สองเมธอดต่อไปนี้คือเมธอดของสคริปต์ อะไรคือความแตกต่างระหว่างเมธอดทั้งสองและฟังก์ชันข้างต้น

  • ความสนุกสาธารณะ : สามารถเรียกใช้เมธอดในโมดูลใดก็ได้

  • public(script) fun / public entry fun: ฟังก์ชันสคริปต์เป็นเมธอดการป้อนข้อมูลในโมดูล ซึ่งหมายความว่าสามารถเรียกเมธอดได้โดยเริ่มต้นธุรกรรมผ่านคอนโซล เช่นเดียวกับการรันสคริปต์ในเครื่อง

Move เวอร์ชันถัดไปจะแทนที่ความสนุกแบบสาธารณะ (สคริปต์) ด้วยความสนุกแบบสาธารณะ

Self แสดงถึงโมดูลของตัวเอง

ใช้ Aptos Cli เพื่อคอมไพล์ ปรับใช้ และเรียกสัญญา

# สร้างสภาพแวดล้อมการทดสอบใหม่
aptos init --profile devtest --rest-url  --faucet-url 
#ทำสัญญาย้ายบ้าน
aptos move compile --package-dir my-counter
#ทำตามสัญญา
# ตัวอย่างเช่น: aptos move publish --package-dir my-counter --named-addresses basecoin=0x8e00bd9827faf171996ef37f006dd622bb5c3e43ec52298a8f37fd38cd59664 --profile devtest
aptos move publish --package-dir my-counter --named-addresses basecoin= --profile devtest
#ทวงสัญญา
# ตัวอย่างเช่น:
# aptos move run --function-id 0x8e00bd9827faf171996ef37f006dd622bb5c3e43ec52298a8f37fd38cd59664::MyCounter::init_counter --profile devtest
# aptos move run --function-id 0x8e00bd9827faf171996ef37f006dd622bb5c3e43ec52298a8f37fd38cd59664::MyCounter::incr_counter --profile devtest
aptos move run --function-id :::: --profile devtest
# แสดงรายการข้อมูลโมดูล/ทรัพยากรของบัญชีที่ระบุ
aptos account list --query modules --account 0xa1285adb4b8abedf5faf7a46d260c5844f1f64d59dd9b8869db1543cf5bbadf4 --profile devtest
aptos account list --query resources --account 0x4200c2b801870f20a709abba80b6edb90a45ecd9b8acce9842b93d597602edcf --profile devtest

Aptos SDK เรียกสัญญา Move

หลังจากรวบรวมสัญญาแล้ว เราสามารถเรียกสัญญาของเราผ่าน sdk

เราสามารถเลือกที่จะปรับใช้สัญญาผ่าน sdk หรือเรียกสัญญาการย้ายผ่าน sdk

  • ปรับใช้สัญญาผ่าน sdk

เมื่อเรารวบรวม build/ โฟลเดอร์จะถูกสร้างขึ้นภายใต้โฟลเดอร์สัญญาการย้าย

เราจำเป็นต้องคัดลอกไฟล์ my-counter/build/Examples/bytecode_modules/MyCounter.mv ไปยังสคริปต์ SDK

aptos move compile --package-dir my-counter
cp MyCounter.mv my-counter-sdk-demo/

  • ปรับใช้รหัส sdk ที่เกี่ยวข้องกับสัญญา

/** Publish a new module to the blockchain within the specified account */
export async function publishModule(accountFrom: AptosAccount, moduleHex: string): Promise {
  const moudleBundlePayload = new TxnBuilderTypes.TransactionPayloadModuleBundle(
    new TxnBuilderTypes.ModuleBundle([new TxnBuilderTypes.Module(new HexString(moduleHex).toUint8Array())]),
  );
  const [{ sequence_number: sequenceNumber }, chainId] = await Promise.all([
    client.getAccount(accountFrom.address()),
    client.getChainId(),
  ]);
  const rawTxn = new TxnBuilderTypes.RawTransaction(
    TxnBuilderTypes.AccountAddress.fromHex(accountFrom.address()),
    BigInt(sequenceNumber),
    moudleBundlePayload,
    1000n,
    1n,
    BigInt(Math.floor(Date.now() / 1000) + 10),
    new TxnBuilderTypes.ChainId(chainId),
  );
  const bcsTxn = AptosClient.generateBCSTransaction(accountFrom, rawTxn);
  const transactionRes = await client.submitSignedBCSTransaction(bcsTxn);
  return transactionRes.hash;
}

  • ส่งธุรกรรมผ่าน SDK

ที่นี่ เราใช้ init_counter และ incr_counter ในสัญญา my-counter เป็นตัวอย่าง

สร้างเมธอดสองเมธอดเพื่อเรียกเมธอดทั้งสองนี้ เพื่อให้ไคลเอนต์สามารถเรียกใช้ฟังก์ชัน init และ incr ได้

async function initCounter(contractAddress: string, accountFrom: AptosAccount): Promise {
  const scriptFunctionPayload = new TxnBuilderTypes.TransactionPayloadScriptFunction(
    TxnBuilderTypes.ScriptFunction.natural(
      `${contractAddress}::MyCounter`,// ที่อยู่สัญญา::ชื่อสัญญา
      "init_counter",// วิธีการทำงานของสคริปต์
      [],
      [],
    ),
  );
  const [{ sequence_number: sequenceNumber }, chainId] = await Promise.all([
    client.getAccount(accountFrom.address()),
    client.getChainId(),
  ]);
  const rawTxn = new TxnBuilderTypes.RawTransaction(
    TxnBuilderTypes.AccountAddress.fromHex(accountFrom.address()),
    BigInt(sequenceNumber),
    scriptFunctionPayload,
    1000n,
    1n,
    BigInt(Math.floor(Date.now() / 1000) + 10),
    new TxnBuilderTypes.ChainId(chainId),
  );
  const bcsTxn = AptosClient.generateBCSTransaction(accountFrom, rawTxn);
  const transactionRes = await client.submitSignedBCSTransaction(bcsTxn);
  return transactionRes.hash;
}
async function incrCounter(contractAddress: string, accountFrom: AptosAccount): Promise {
  const scriptFunctionPayload = new TxnBuilderTypes.TransactionPayloadScriptFunction(
    TxnBuilderTypes.ScriptFunction.natural(
      `${contractAddress}::MyCounter`,
      "incr_counter",
      [],
      [],
    ),
  );
  const [{ sequence_number: sequenceNumber }, chainId] = await Promise.all([
    client.getAccount(accountFrom.address()),
    client.getChainId(),
  ]);
  const rawTxn = new TxnBuilderTypes.RawTransaction(
    TxnBuilderTypes.AccountAddress.fromHex(accountFrom.address()),
    BigInt(sequenceNumber),
    scriptFunctionPayload,
    1000n,
    1n,
    BigInt(Math.floor(Date.now() / 1000) + 10),
    new TxnBuilderTypes.ChainId(chainId),
  );
  const bcsTxn = AptosClient.generateBCSTransaction(accountFrom, rawTxn);
  const transactionRes = await client.submitSignedBCSTransaction(bcsTxn);
  return transactionRes.hash;
}

  • รับข้อมูลทรัพยากรในบัญชีผ่าน SDK

ทรัพยากรถูกจัดเก็บภายใต้ที่อยู่บัญชีที่เป็นเจ้าของ และเราสามารถสืบค้นข้อมูลทรัพยากรที่เกี่ยวข้องตามที่อยู่บัญชีได้

เมธอด getCounter() คือการรับทรัพยากร **Counter** ภายใต้ my-counter


async function getCounter(contractAddress: string, accountAddress: MaybeHexString): Promise {
  try {
    const resource = await client.getAccountResource(
      accountAddress.toString(),
      `${contractAddress}::MyCounter::Counter`,
    );
    return (resource as any).data["value"];
  } catch (_) {
    return "";
  }
}

อันที่จริงแล้วเอฟเฟกต์นี้คล้ายกับใน sdk

aptos account list --query resources --account 0x4200c2b801870f20a709abba80b6edb90a45ecd9b8acce9842b93d597602edcf

หน้าที่หลักขั้นสุดท้าย

async function main() {
  assert(process.argv.length == 3, "Expecting an argument that points to the helloblockchain module");
  const contractAddress = "0x173d51b1d50614b03d0c18ffcd958309042a9c0579b6b21fc9efeb48cdf6e0b0"; // ระบุที่อยู่ของสัญญาที่ใช้งานก่อนหน้านี้
const bob = new AptosAccount(); // สร้างที่อยู่ทดสอบ Bob
  console.log("\n=== Addresses ===");
  console.log(`Bob: ${bob.address()}`);
  await faucetClient.fundAccount(bob.address(),5_000); // ส่งโทเค็นทดสอบ Airdrop 5,000 รายการไปยังที่อยู่ของ Bob
  console.log("\n=== Initial Balances ===");
  console.log(`Bob: ${await accountBalance(bob.address())}`);
  await new Promise((resolve) => {
    readline.question(
      "Update the module with Alice's address, build, copy to the provided path, and press enter.",
      () => {
        resolve();
        readline.close();
      },
    );
  });
  const modulePath = process.argv[2];
  const moduleHex = fs.readFileSync(modulePath).toString("hex");
  console.log('Init Counter Moudle.');
  let txHash = await initCounter(contractAddress,bob); // init Counter ทรัพยากรภายใต้ bob ขณะนี้ค่าของ Counter ภายใต้ bob คือ 0
  await client.waitForTransaction(txHash);
  console.log("\n=== Testing Bob Get Counter Value ===");
  console.log(`Initial value: ${await getCounter(contractAddress, bob.address())}`);
  console.log('========== Incr Counter Value, 1th ==========');
  txHash = await incrCounter(contractAddress,bob); // bob เรียกใช้เมธอด incrCounter หนึ่งครั้ง และตอนนี้ Counter เป็น 1
  console.log(txHash);
  await client.waitForTransaction(txHash);
  await Sleep(100);
  console.log(`New value: ${await getCounter(contractAddress,bob.address())}`); // รับค่า Counter ใต้ address ของ bob แล้วส่งออก
  console.log('========== Incr Counter Value, 2th ==========');
  txHash = await incrCounter(contractAddress,bob); // bob เรียกใช้เมธอด incrCounter หนึ่งครั้ง และตัวนับคือ 2
  console.log(txHash);
  await client.waitForTransaction(txHash);
  await Sleep(100);
  console.log(`New value: ${await getCounter(contractAddress,bob.address())}`); // รับค่า Counter ใต้ address ของ bob แล้วแสดงผลออกมา
  console.log('========== Incr Counter Value, 3th ==========');
  txHash = await incrCounter(contractAddress,bob); // bob เรียกใช้เมธอด incrCounter หนึ่งครั้ง และตัวนับคือ 3
  console.log(txHash);
  await client.waitForTransaction(txHash);
  await Sleep(100);
  console.log(`New value: ${await getCounter(contractAddress,bob.address())}`); // รับค่า Counter ใต้ address ของ bob แล้วส่งออก
}
if (require.main === module) {
  main().then((resp) => console.log(resp));
}

ผลการดำเนินการ

การดำเนินการสำเร็จ ที่นี่ ผ่าน SDK บัญชีที่สร้างขึ้นแบบสุ่มเริ่มต้นด้วยทรัพยากรตัวนับ (ตัวนับ=0) จากนั้นเพิ่มขึ้นสามครั้ง ดังนั้นค่าสุดท้ายของตัวนับคือ 3

image-20220831200516865

อ้างอิง

อ้างอิง

[1]Using CLI to Run a Local Testnet | Aptos Docs: https://aptos.dev/nodes/local-testnet/using-cli-to-run-a-local-testnet

[2] ซอร์สโค้ด: https://github.com/aptos-labs/aptos-core/blob/main/aptos-move/framework/move-stdlib/sources/signer.move


Aptos
ยินดีต้อนรับเข้าร่วมชุมชนทางการของ Odaily
กลุ่มสมาชิก
https://t.me/Odaily_News
กลุ่มสนทนา
https://t.me/Odaily_CryptoPunk
บัญชีทางการ
https://twitter.com/OdailyChina
กลุ่มสนทนา
https://t.me/Odaily_CryptoPunk
ค้นหา
สารบัญบทความ
คลังบทความของผู้เขียน
DAOrayaki
ดาวน์โหลดแอพ Odaily พลาเน็ตเดลี่
ให้คนบางกลุ่มเข้าใจ Web3.0 ก่อน
IOS
Android