admin管理员组

文章数量:1391944

I'm posting my problem here as I'm new to Aptos and I'm facing an issue I havn't found any solution online before. I've recently joined a team and they are codding using Move that basic multisig escrow contract and I have to test my contract using the integrated CLI for Aptos.

Here is the function I want to test:

module TradeSafeMultisig::tradesafe_multisig {
    use std::vector;
    use std::option::{Self, Option};
    use aptos_std::simple_map::{Self, SimpleMap};
    use aptos_framework::account::{Self, SignerCapability};
    use std::bcs::to_bytes;
    use std::signer;
    use aptos_framework::aptos_coin::AptosCoin;
    use aptos_framework::coin;
    use aptos_framework::aptos_account;

    const DOMAIN_SEPARATOR: vector<u8> = b"aptos_framework::multisig_account";

    struct Proposal has copy, store, drop {
        recipient: address,
        amount: u64,
        timestamp_secs: Option<u64>, // Timestamp of proposal expiration / activation
        votes: SimpleMap<address, bool>, // Tracks votes
    }

    struct MultisigInstance has key, store {
        owners: vector<address>, // Owners of the multisig
        threshold: u64,          // Approval threshold
        payment_proposal: Option<Proposal>, // Payment proposal
        refund_proposal: Option<Proposal>,  // Refund proposal
        signer_cap: SignerCapability, // Signer capability
    }

    /// Generate a seed for creating the resource account.
    fun create_multisig_account_seed(seed: vector<u8>): vector<u8> {
        let multisig_account_seed = vector::empty<u8>();
        vector::append(&mut multisig_account_seed, DOMAIN_SEPARATOR);
        vector::append(&mut multisig_account_seed, seed);
        multisig_account_seed
    }

    #[test_only]
    public fun create_multisig_account_seed_test(seed: vector<u8>): vector<u8> {
        create_multisig_account_seed(seed)
    }

    /// Create a new multisig instance
    public entry fun create_multisig(
        creator: &signer,
        owners: vector<address>, 
        threshold: u64
    ) {
        assert!(threshold > 0, 1); // Valid threshold
        assert!(threshold <= vector::length(&owners), 2); // Threshold cannot exceed owner count

        let creator_address = signer::address_of(creator);
        let creator_nonce = account::get_sequence_number(creator_address);
        let (multisig_account, multisig_signer_cap) =
            account::create_resource_account(creator, create_multisig_account_seed(to_bytes(&creator_nonce)));

        // Ensure the multisig account is registered for APT transfers
        if (!coin::is_account_registered<AptosCoin>(signer::address_of(&multisig_account))) {
            coin::register<AptosCoin>(&multisig_account);
        };

        move_to(&multisig_account, MultisigInstance {
            owners,
            threshold,
            payment_proposal: option::none<Proposal>(), // No active payment proposal initially
            refund_proposal: option::none<Proposal>(), // No active refund proposal initially
            signer_cap: multisig_signer_cap,
        });
    }

As you can see, the function will update the Global Storage, adding a new multisig related to the user and I want to create a testing workflow that will basically create a multisig for a dummy user, and then executes all the corresponding actions.

I've facing tons of problems trying to test this function as everytime I'm calling my function, this line raise an error

   let creator_nonce = account::get_sequence_number(creator_address);

The error is raising that the compilator cannot access the account's global storage sequence number.

borrow_global<Account>(addr).sequence_number
│     │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to error, but it gave a MISSING_DATA (code 4008) error with error message: "Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001". Error originating in the module 0000000000000000000000000000000000000000000000000000000000000001::account rooted here

The account (signer) I'm using is the basic one imjected by the

#[test(a = @0x1, b = @0x2)]

I think I have to initialize in a way my signer to use it and retrieve it's sequence number but after trying almost every way account::create_account and aptos_framework::create_account it's seems that there's always an error at the end.

I must be doing something completely wrong here and I'm asking for you help here to show me the good practice and architecture for testing my function

Here is the full draft testing function I'm codding on now:

    #[test(a = @0x1, b = @0x2)]
    fun test_create_multisig(a: signer, b: address) {
          // Publish the Account resource at address a

        let creator_address = signer::address_of(&a);
        // let sequence = account::get_sequence_number(&a);
        let owners: vector<address> = vector[
            creator_address,
            b
        ];
        let threshold = 2;
        create_multisig(&a, owners, threshold);
        // let payment_proposal = tradesafe_multisig::view_payment_proposal(signer::address_of(&multisig_account));
        // assert!(option::is_none(&payment_proposal), 1);
    }

Thank you very much in advance to anyone helping me out ! :)

I'm posting my problem here as I'm new to Aptos and I'm facing an issue I havn't found any solution online before. I've recently joined a team and they are codding using Move that basic multisig escrow contract and I have to test my contract using the integrated CLI for Aptos.

Here is the function I want to test:

module TradeSafeMultisig::tradesafe_multisig {
    use std::vector;
    use std::option::{Self, Option};
    use aptos_std::simple_map::{Self, SimpleMap};
    use aptos_framework::account::{Self, SignerCapability};
    use std::bcs::to_bytes;
    use std::signer;
    use aptos_framework::aptos_coin::AptosCoin;
    use aptos_framework::coin;
    use aptos_framework::aptos_account;

    const DOMAIN_SEPARATOR: vector<u8> = b"aptos_framework::multisig_account";

    struct Proposal has copy, store, drop {
        recipient: address,
        amount: u64,
        timestamp_secs: Option<u64>, // Timestamp of proposal expiration / activation
        votes: SimpleMap<address, bool>, // Tracks votes
    }

    struct MultisigInstance has key, store {
        owners: vector<address>, // Owners of the multisig
        threshold: u64,          // Approval threshold
        payment_proposal: Option<Proposal>, // Payment proposal
        refund_proposal: Option<Proposal>,  // Refund proposal
        signer_cap: SignerCapability, // Signer capability
    }

    /// Generate a seed for creating the resource account.
    fun create_multisig_account_seed(seed: vector<u8>): vector<u8> {
        let multisig_account_seed = vector::empty<u8>();
        vector::append(&mut multisig_account_seed, DOMAIN_SEPARATOR);
        vector::append(&mut multisig_account_seed, seed);
        multisig_account_seed
    }

    #[test_only]
    public fun create_multisig_account_seed_test(seed: vector<u8>): vector<u8> {
        create_multisig_account_seed(seed)
    }

    /// Create a new multisig instance
    public entry fun create_multisig(
        creator: &signer,
        owners: vector<address>, 
        threshold: u64
    ) {
        assert!(threshold > 0, 1); // Valid threshold
        assert!(threshold <= vector::length(&owners), 2); // Threshold cannot exceed owner count

        let creator_address = signer::address_of(creator);
        let creator_nonce = account::get_sequence_number(creator_address);
        let (multisig_account, multisig_signer_cap) =
            account::create_resource_account(creator, create_multisig_account_seed(to_bytes(&creator_nonce)));

        // Ensure the multisig account is registered for APT transfers
        if (!coin::is_account_registered<AptosCoin>(signer::address_of(&multisig_account))) {
            coin::register<AptosCoin>(&multisig_account);
        };

        move_to(&multisig_account, MultisigInstance {
            owners,
            threshold,
            payment_proposal: option::none<Proposal>(), // No active payment proposal initially
            refund_proposal: option::none<Proposal>(), // No active refund proposal initially
            signer_cap: multisig_signer_cap,
        });
    }

As you can see, the function will update the Global Storage, adding a new multisig related to the user and I want to create a testing workflow that will basically create a multisig for a dummy user, and then executes all the corresponding actions.

I've facing tons of problems trying to test this function as everytime I'm calling my function, this line raise an error

   let creator_nonce = account::get_sequence_number(creator_address);

The error is raising that the compilator cannot access the account's global storage sequence number.

borrow_global<Account>(addr).sequence_number
│     │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to error, but it gave a MISSING_DATA (code 4008) error with error message: "Failed to borrow global resource from 0000000000000000000000000000000000000000000000000000000000000001". Error originating in the module 0000000000000000000000000000000000000000000000000000000000000001::account rooted here

The account (signer) I'm using is the basic one imjected by the

#[test(a = @0x1, b = @0x2)]

I think I have to initialize in a way my signer to use it and retrieve it's sequence number but after trying almost every way account::create_account and aptos_framework::create_account it's seems that there's always an error at the end.

I must be doing something completely wrong here and I'm asking for you help here to show me the good practice and architecture for testing my function

Here is the full draft testing function I'm codding on now:

    #[test(a = @0x1, b = @0x2)]
    fun test_create_multisig(a: signer, b: address) {
          // Publish the Account resource at address a

        let creator_address = signer::address_of(&a);
        // let sequence = account::get_sequence_number(&a);
        let owners: vector<address> = vector[
            creator_address,
            b
        ];
        let threshold = 2;
        create_multisig(&a, owners, threshold);
        // let payment_proposal = tradesafe_multisig::view_payment_proposal(signer::address_of(&multisig_account));
        // assert!(option::is_none(&payment_proposal), 1);
    }

Thank you very much in advance to anyone helping me out ! :)

Share Improve this question asked Mar 13 at 12:53 jbrionnejbrionne 11 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 0

Alright, I managed to find the correct test structure.

So basically, when starting a Move test, you have absolutely nothing settled up, so you have to initialize almost everything for your test ! I used this repo to understand slowly but surely how it's going

Aptos Repository

So I had to initialize my signer account so it could retrieve it's sequence number and I also had to initialize the APT token as it was not natively deployed in my test environement.

Here is my code now

    use std::signer;
    use std::vector;
    use std::bcs::to_bytes;
    use aptos_framework::account::{Self, SignerCapability};
    use aptos_framework::aptos_coin;
    use aptos_framework::aptos_coin::AptosCoin;
    use aptos_framework::coin;
    use aptos_framework::account::create_signer_for_test;
    use aptos_framework::account::create_account_for_test;
    use aptos_framework::aptos_account;
    
    fun init_aptos_coin() {
        let coin_core = create_signer_for_test(@0x1);
        let (burn_cap, mint_cap) = aptos_framework::aptos_coin::initialize_for_test(&coin_core);

        coin::destroy_burn_cap(burn_cap);
        coin::destroy_mint_cap(mint_cap);
    }


    #[test(xtraa = @0x69610, xtraa2 = @0x69003)]
    public fun test_multisig_initialization(xtraa: &signer, xtraa2: &signer) {

        init_aptos_coin();
        create_account_for_test(signer::address_of(xtraa));
}

This may not be the best way, but so far, it's working and I hope this could help you one day !

本文标签: blockchainAptos Unit Testing Account InitializationsStack Overflow