为什么这个合约调用会出错?

Why is there an error in this contract call?

nearprotocol 的新手!尝试使用 near-api-js 做一个小小的 hello world,这是我的问题...

const { keyStores, connect } = require("near-api-js");
const fs = require("fs");
const path = require("path");
const homedir = require("os").homedir();

const CREDENTIALS_DIR = ".near-credentials";
const ACCOUNT_ID = "acct.testnet";
const WASM_PATH = "./contract/target/wasm32-unknown-unknown/release/counter.wasm";

const credentialsPath = path.join(homedir, CREDENTIALS_DIR);
const keyStore = new keyStores.UnencryptedFileSystemKeyStore(credentialsPath);

const config = {
    keyStore,
    networkId: "testnet",
    nodeUrl: "https://rpc.testnet.near.org",
};

deployContract(ACCOUNT_ID, WASM_PATH);

async function deployContract(accountId, wasmPath) { 
    const near = await connect(config);
    const account = await near.account(accountId);
    const result = await account.deployContract(fs.readFileSync(wasmPath));
}

我正在使用这种方法部署 wasm 合约,但是,当我尝试使用

调用合约时
const nearAPI = require("near-api-js");
const keyStores = nearAPI.keyStores;
const connect = nearAPI.connect;

const homedir = require("os").homedir();
const CREDENTIALS_DIR = ".near-credentials";
const credentialsPath = require("path").join(homedir, CREDENTIALS_DIR);
const keyStore = new keyStores.UnencryptedFileSystemKeyStore(credentialsPath);

const config = {
  networkId: "testnet",
  keyStore, 
  nodeUrl: "https://rpc.testnet.near.org",
  walletUrl: "https://wallet.testnet.near.org",
  helperUrl: "https://helper.testnet.near.org",
  explorerUrl: "https://explorer.testnet.near.org",
};

call();

async function call() {
    // gets the state of the account
    const near = await connect(config);
    const account = await near.account("acct.testnet");

    const contract = new nearAPI.Contract(
        account, // the account object that is connecting
        "acct.testnet",
        {
            contractID : "counter.acct.testnet",
            changeMethods: ["increment", "decrement", "reset"], // view methods do not change state but usually return a value
            viewMethods: ["get_num"], // change methods modify state
            sender: account, // account object to initialize and sign transactions.
        }
    );

    let response = await contract.reset(
        {
          args: {
              //arg_name: "value" // argument name and value - pass empty object if no args required
          },
          gas: 300000000000000 // attached GAS (optional)
        }
    );
    
    console.log(response);
}

现在,响应说合同不存在:ServerTransactionError: Can't complete the action because account counter.acct.testnet doesn't exist

但是,当使用 acct.testnet 而不是 counter.acct.testnet 时,它起作用了。

这留下了一个问题:我如何在附近的区块链上,在特定帐户下指定我想要与之交互的确切合约?

谢谢!

您可以通过两种不同的方式使用 NAJ (near-api-js) 并与合约进行交互。第一种方法,也就是您正在使用的方法,是创建一个合约对象 (new nearAPI.Contract()) 并使用帐户对象连接到合约(来自钱包连接或本机 near.account() 方法):

const contract = new nearAPI.Contract(
        accountObject, // the account object that is connecting
        ...

此方法允许您传入您希望与之交互的合约的帐户 ID:

const contract = new nearAPI.Contract(
        accountObject,
        "CONTRACT_ACCOUNT_ID_HERE.testnet",
        ...

在您的情况下,只需将该帐户 ID 更改为您想要的任何内容,这样您就可以与不同的合约进行交互。这些帐户 ID 必须存在并且还部署了合约,否则你会 运行 出错。不要忘记,您在创建 nearAPI 合约对象时概述的方法也必须存在于合约中,否则当您尝试使用它们时,它也会抛出异常。

与合同交互的第二种方式,这是我喜欢的做事方式,是以与之前相同的方式创建帐户对象,而不是创建合同对象并执行 contract.methodName,你只需获取帐户对象并执行 account.functionCallaccount.viewFunction,你可以在其中传递合约 ID、方法名称等...

这使您可以与任何合约进行交互on-chain,而无需为您要与之交互的每个合约创建一个新的合约对象。