NEAR Documentation
  • Basics
  • Develop
  • Stake
  • Integrate
  • Tokens
  • Contribute
  • API
  • Community
  • GitHub

›Guided Walkthroughs

Quickstart

  • Orientation
  • Building Apps
  • Networks

Tutorials

  • Introduction
  • Guided Walkthroughs

    • Figment Tutorials
    • Create Transactions
    • Issue a Token
    • Cross-Contract Calls
    • Simple AssemblyScript tests
    • Simple Rust smart contract

    Helpful References

    • Contract Structure
    • Project Structure

    Videos

    • Accounts & keys
    • Smart Contract Reviews
    • Misc

JavaScript library

  • Introduction
  • Guides
  • Examples

Smart Contracts

  • Introduction
  • Creating Contracts

    • Rust
    • AssemblyScript

    Using Contracts

    • Rust
    • JavaScript
    • API

    Testing Contracts

    • Testing contracts

    Virtual Machine Limits

    • Runtime Limits

Ethereum Compatibility

  • Network status
  • Simple script & NEAR CLI guide
  • Pet Shop example
  • Web3 provider
  • Using Truffle
  • Local setup
  • Proxy RPC Server
  • Testing contracts

Machine Setup

  • Local Development on TestNet
  • Local Development on Local Network
  • Running a node
  • Running a Node on Windows

FAQ

  • Developer FAQ
Edit

Create Transactions

To construct & process transactions you will need our API JavaScript library: near-api-js.

  • All transactions require the following:
    • signerId (account ID of the transaction originator)
    • signerPublicKey
    • receiverId (account ID of the transaction recipient)
    • nonceForPublicKey (each time a key is used the nonce value should be incremented by 1)
    • actions ( [ click here ] for supported arguments)
    • blockHash (a current block hash (within 24hrs) to prove the transaction was recently created)

See Transaction Class for a more in depth outline.

Note: This is a very low level approach for creating transactions on NEAR. Our JavaScript library, near-api-js, provides much higher level ways to create transactions. See working examples of this at NEAR.dev.


Create a "token transfer" transaction

Setup

  1. Clone the transaction-examples repository by running:
git clone https://github.com/near-examples/transaction-examples.git
  1. Follow setup instructions

Imports

In send-tokens-deconstructed.js we use three dependencies:

  1. NEAR API JavaScript library
  2. js-sha256 (cryptographic hashing algorithm)
  3. dotenv (used to load environment variables)
const nearAPI = require('near-api-js');
const sha256 = require('js-sha256');
require('dotenv').config();

Accounts & Network

Next, you'll need to enter the accountId of the sender and receiver, as well as the networkId (betanet, testnet, or mainnet).

const sender = 'sender.testnet';
const receiver = 'receiver.testnet';
const networkId = 'testnet';

Formatting Token Amounts

When sending NEAR tokens (Ⓝ) during a transaction, the amount needs to be converted into Yocto Ⓝ or (10^-24).

  • To perform this you will use the near-api-js method parseNearAmount() (located in utils/format)
const amount = nearAPI.utils.format.parseNearAmount('1.5');

Setting up a connection to NEAR

In this example, we will create a NEAR RPC provider that allows us to interact with the chain via RPC endpoints.

const provider = new nearAPI.providers
  .JsonRpcProvider(`https://rpc.${networkId}.near.org`);

Access Keys

To sign a transaction to send NEAR Ⓝ, we will need a FullAccess key to the sender's account.

  • If you created the account using near-cli or ran near login in your terminal, your private key can be found in a .json file located in /HOME/.near-credentials.
  • If you created an account using NEAR Wallet, your key will be found in your browser's Local Storage.
    • In your browser's dev tools... Application >> Storage >> Local Storage

Once you have access to the private key of the sender's account, create an environment variable SENDER_PRIVATE_KEY or hard code it as a string on line 18 of send-tokens.js.

  • With this privateKey, we can now construct a keyPair object to sign transactions.
const privateKey = process.env.SENDER_PRIVATE_KEY
const keyPair = nearAPI.utils.key_pair.KeyPairEd25519.fromString(privateKey)

Transaction Requirements

As stated before, all transactions require six parts:

  1. signerId
  2. signerPublicKey
  3. receiverId
  4. nonceForPublicKey
  5. actions
  6. blockHash

1 signerId

  • The signerId is the account ID of the transaction originator.
  • This value is passed as a string (ex. 'example.testnet' or 'bob.near')

2 signerPublicKey

  • The signerPublicKey is required to be an object with two key value pairs: keyType and data.
PublicKey = {
  keyType: 0,
  data: Uint8Array(32) [
    190, 150, 152, 145, 232, 248, 128,
    151, 167, 165, 128,  46,  20, 231,
    103, 142,  39,  56, 152,  46, 135,
      1, 161, 180,  94, 212, 195, 201,
     73, 190,  70, 242
  ]
}
  • This can be constructed by calling getPublicKey() using the keyPair we setup earlier.
const publicKey = keyPair.getPublicKey();

3 receiverId

  • The receiverId is the account ID of the transaction recipient.
  • This value is passed as a string (ex. 'example.testnet' or 'bob.near')
  • The certain cases, the signerId and the receiverId can be the same account.

4 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.
  • Current nonce can be retrieved using the provider we created earlier.
const accessKey = await provider.query(
  `access_key/${sender}/${publicKey.toString()}`, ''
  );
  • now we can create a unique number for our transaction by incrementing the current nonce.
const nonce = ++accessKey.nonce;

5 actions

  • There are currently eight supported Action types. [ see here ]
  • For this example, we are using Transfer
  • This transfer action can be created using the imported nearAPI object and the formatted Ⓝ amount created earlier.
const actions = [nearAPI.transactions.transfer(amount)];

[ click here ] to view source for transfer().

6 blockHash

  • Each transaction requires a current block hash (within 24hrs) to prove that the transaction was created recently.
  • Hash must be converted to an array of bytes using the base_decode method found in nearAPI.
const recentBlockHash = nearAPI.utils.serialize.base_decode(accessKey.block_hash)

[ click here ] to view source for base_decode().


Constructing the Transaction

With all of our required arguments, we can construct the transaction.

  • Using nearAPI, we call on createTransaction() to perform this task.
const transaction = nearAPI.transactions.createTransaction(
  sender, 
  publicKey, 
  receiver, 
  nonce, 
  actions, 
  recentBlockHash
  );

[ click here ] to view source code for the Transaction class


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 = nearAPI.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')]
  );

Transaction Results

Detailed transaction results of the transaction are returned in the following format:

{
  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'
}

For detailed information on transaction receipts [ click here ]

  • To view the transaction in NEAR Explorer, enter the hash located under transaction / Transaction Results.
  • In addition, you can create a link in JS using the networkId and result.transaction.hash.
const transactionLink = `https://explorer.${networkId}.near.org/transactions/${result.transaction.hash}`

Got a question? Ask it on StackOverflow!

Happy Coding! 🚀

Last updated on 1/20/2021 by Josh
← Figment TutorialsIssue a Token →
  • Setup
  • Imports
  • Accounts & Network
  • Formatting Token Amounts
  • Setting up a connection to NEAR
  • Access Keys
  • Transaction Requirements
    • 1 signerId
    • 2 signerPublicKey
    • 3 receiverId
    • 4 nonceForPublicKey
    • 5 actions
    • 6 blockHash
  • Constructing the Transaction
  • Sign Transaction
  • Send Transaction
  • Transaction Results
  • Wallet
  • Explorer
  • Examples
  • Docs
  • Twitter
  • GitHub
  • Discord
  • Telegram
  • WeChat
  • YouTube

Developers

  • Overview
  • Technology
  • Docs
  • GitHub
  • Bounties
  • Developer Program
  • Survey

Ecosystem

  • Events
  • Contributor Program
  • Guild Program
  • Startup Accelerator
  • Bounties
  • Tokens

About

  • Team
  • Careers
  • Backers
  • Press Kit
  • Brand Guidelines
  • Privacy Policy

2020 NEAR Protocol|All rights reserved|hello@near.org|Privacy Policy