Nhảy đến nội dung chính

Remote Procedural Call

Here we will only briefly mention how to use the NEAR RPC. If you want to find the full documentation on NEAR RPC please follow this link.


View Methods

View methods are those that perform read-only operations. Calling these methods is free, and do not require to specify which account is being used to make the call:

  • method: query
  • params:
    • request_type: call_function
    • finality OR block_id
    • account_id: "example.testnet"
    • method_name: name_of_a_example.testnet_method
    • args_base64: method_arguments_base_64_encoded
{
"jsonrpc": "2.0",
"id": "dontcare",
"method": "query",
"params": {
"request_type": "call_function",
"finality": "final",
"account_id": "dev-1588039999690",
"method_name": "get_num",
"args_base64": "e30="
}
}
Example response:

{
"jsonrpc": "2.0",
"result": {
"result": [48],
"logs": [],
"block_height": 17817336,
"block_hash": "4qkA4sUUG8opjH5Q9bL5mWJTnfR4ech879Db1BZXbx6P"
},
"id": "dontcare"
}

Note: [48] is an array of bytes, to be specific it is an ASCII code of 0.near-sdk-rs and near-sdk-js return JSON-serialized results.

What could go wrong? If you encounter a error please check the RPC docs :::

Change Methods

Change methods are those that perform both read and write operations. For these methods we do need to specify the account being used to make the call, since that account will expend GAS in the call.

Since calls to change methods need to be signed by an account, you will first need to create and sign the transaction that you want to send to the RPC. For this, you currently need to make heavy use of near-api-js. Particularly, you need to:

  1. Create a transaction using the near-api-js.transactions module.
  2. Sign the transaction using the near-api-js.KeyStore.KeyPair
  3. Send the signed transaction to the RPC.

Create Transaction

In order yo create a transaction you will use near-api-js.transactions.createTransaction which takes as input:

  1. signerId: the account ID of the transaction originator.
  2. signerPublicKey: the signer public key, see bellow.
  3. receiverId: the account ID of the transaction recipient.
  4. nonceForPublicKey: a unique number, see bellow
  5. actions: An action, built from near-api-js.transactions.
  6. blockHash

signerPublicKey

The public key of the signer must be encoded as an object with two key value pairs: keyType and data. Here is one possible way to get it:

const privateKey = "private-key-here";
const keyPair = nearAPI.utils.key_pair.KeyPairEd25519.fromString(privateKey);
const publicKey = keyPair.getPublicKey()

nonceForPublicKey

A unique number or nonce is required for each transaction signed with an access key. To ensure a unique number is created for each transaction, the current nonce should be queried and then incremented by 1.


const provider = new near-api-js.providers.JsonRpcProvider(
`https://rpc.testnet.near.org`
);
const accessKey = await provider.query(
`access_key/influencer.testnet/${publicKey.getPublicKey().toString()}`,
""
);

const nonce = accessKey.nonce + 1;

blockHash

Each transaction requires a current block hash (within 24hrs) to prove that the transaction was created recently. The hash must be converted to an array of bytes using the base_decode method found in near-api-js.

const recentBlockHash = near-api-js.utils.serialize.base_decode(
accessKey.block_hash
);

Sign Transaction

Now that the transaction is created, we sign it before sending it to the NEAR blockchain. At the lowest level, there are four steps to this process.

  1. Using nearAPI, we call on serialize() to serialize the transaction in Borsh.
const serializedTx = near-api-js.utils.serialize.serialize(
nearAPI.transactions.SCHEMA,
transaction
);
  1. Hash the serialized transaction using a sha256 cryptographic hashing algorithm.
const serializedTxHash = new Uint8Array(sha256.sha256.array(serializedTx));
  1. Create a signature with the keyPair.
const signature = keyPair.sign(serializedTxHash);
  1. Construct the signed transaction using near-api-js SignedTransaction class.
const signedTransaction = new nearAPI.transactions.SignedTransaction({
transaction,
signature: new nearAPI.transactions.Signature({
keyType: transaction.publicKey.keyType,
data: signature.signature,
}),
});

Send Transaction

Final step is to encode and send the transaction.

  • First we serialize transaction into Borsh, and store the result as signedSerializedTx. (required for all transactions)
  • Then we send the transaction via RPC call using the sendJsonRpc() method nested inside near.
// encodes transaction to serialized Borsh (required for all transactions)
const signedSerializedTx = signedTransaction.encode();
// sends transaction to NEAR blockchain via JSON RPC call and records the result
const result = await provider.sendJsonRpc("broadcast_tx_commit", [
Buffer.from(signedSerializedTx).toString("base64"),
]);
Example response:
{
status: { SuccessValue: '' },
transaction: {
signer_id: 'sender.testnet',
public_key: 'ed25519:8RazSLHvzj4TBSKGUo5appP7wVeqZNQYjP9hvhF4ZKS2',
nonce: 57,
receiver_id: 'receiver.testnet',
actions: [ [Object] ],
signature: 'ed25519:2sK53w6hybSxX7qWShXz6xKnjnYRUW7Co3evEaaggNW6pGSCNPvx7urY4akwnzAbxZGwsKjx8dcVm73qbitntJjz',
hash: 'EgGzB73eFxCwZRGcEyCKedLjvvgxhDXcUtq21SqAh79j'
},
transaction_outcome: {
proof: [ [Object] ],
block_hash: 'J6cFDzAFkuknHMCEYW2uPQXDvCfSndkJmADVEWJbtTwV',
id: 'EgGzB73eFxCwZRGcEyCKedLjvvgxhDXcUtq21SqAh79j',
outcome: {
logs: [],
receipt_ids: [Array],
gas_burnt: 223182562500,
tokens_burnt: '22318256250000000000',
executor_id: 'sender.testnet',
status: [Object]
}
},
receipts_outcome: [
{
proof: [Array],
block_hash: 'FSS7UzTpMr4mUm6aw8MmzP6Q7wnQs35VS8vYm1R461dM',
id: '3LjBxe2jq1s7XEPrYxihp4rPVdyHAbYfkcdJjUEVijhJ',
outcome: [Object]
},
{
proof: [Array],
block_hash: '4XBio5dM5UGYjJgzZjgckfVgMZ9uKGbTkt8zZi5webxw',
id: 'AXFA4kwiYfruKQ4LkD1qZA8P7HoAvtFwGqwQYdWtWNaW',
outcome: [Object]
}
]
}
Transaction Results: {
signer_id: 'sender.testnet',
public_key: 'ed25519:8RazSLHvzj4TBSKGUo5appP7wVeqZNQYjP9hvhF4ZKS2',
nonce: 57,
receiver_id: 'receiver.testnet',
actions: [ { Transfer: [Object] } ],
signature: 'ed25519:2sK53w6hybSxX7qWShXz6xKnjnYRUW7Co3evEaaggNW6pGSCNPvx7urY4akwnzAbxZGwsKjx8dcVm73qbitntJjz',
hash: 'EgGzB73eFxCwZRGcEyCKedLjvvgxhDXcUtq21SqAh79j'
}