Skip to content
This repository has been archived by the owner on May 6, 2020. It is now read-only.

summa-tx/near-web3-provider

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NOTE: THIS IS ALPHA SOFTWARE

near-web3-provider

NEAR Protocol Web3 provider. Use it to connect your Ethereum frontend or Truffle to NEAR Protocol.

Install

$ npm install near-web3-provider

Running Tests

Tests require running a local nearcore.

Install Rustup:

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Add wasm target to your toolchain:

$ rustup target add wasm32-unknown-unknown

Install and run NEARCore using Docker:

$ git clone https://github.com/nearprotocol/nearcore
$ cd nearcore
$ make docker-nearcore
$ ./scripts/start_localnet.py

To run NEARcore without Docker

$ git clone https://github.com/nearprotocol/nearcore
$ cd nearcore
$ ./scripts/start_localnet.py --nodocker

Run tests

$ npm run test

Tests currently take ~50 seconds to run.

Requirements

Node > 11.0

General Usage

You can use this provider wherever a Web3 provider is needed.

const { NearProvider, nearlib } = require('near-web3-provider');

const nearNetworkId = '<local, default, test, etc>'; // default is 'default'
const accountId = '<account id to use for tx>';
const keyStore = new nearlib.keyStores.<one of keyStores>;

const web = new Web3();
web.setProvider(new NearProvider("<url to NEAR RPC>", keyStore, accountId, nearNetworkId));
web.eth.net.isListening();

Using in Truffle

Add to your truffle-config.json:

// Import NearProvider and nearlib
const { NearProvider, nearlib } = require('near-web3-provider');

// Specify which NEAR network to use
const nearNetworkId = '<local, default, test, etc>';

// If developing against a local node, use http://localhost:3030
const url = 'https://rpc.nearprotocol.com';

// Specify where to store keys
const keyDir = 'neardev';

// Use standard near-shell structure for storing keys. See note below for other options.
const keyStore = new nearlib.keyStores.UnencryptedFileSystemKeyStore(keyDir);

// Account ID
const accountId = 'test.account';

module.exports = {
  networks: {
    near: {
        network_id: "99",
        skipDryRun: true,
        provider: function() {
            return new NearProvider(url, keyStore, accountId, nearNetworkId)
        },
    }
  }
}

See key store documentation for other options.

Differences from Ethereum providers

NEAR Protocol is a sharded, proof-of-stake blockchain. Keeping that in mind, some Ethereum concepts are naturally not shared with NEAR; for example, there is no concept of uncle blocks, pending blocks, or block difficulty.

As a sharded blockchain, the structure of NEAR blocks is also different. In Ethereum, blocks have transactions. In NEAR, blocks have chunks, and chunks have transactions.

near-web3-provider has been adapted to follow the Ethereum JSON RPC API and its web3 equivalents as closely as possible. Where there are no equivalents, empty values have been passed through. Other return values have been adapted to account for the difference in block structure (for example, the root of the transaction trie comes from a chunk rather than a block).

Mining, hashrates, ssh, and db methods are not supported.

Limitations

  • Methods that have an extra default block parameter will function as latest, regardless of the actual argument. This is a Near RPC limitation.

  • eth_call does not support from or value arguments. This is a Near RPC limitation.

  • eth_estimateGas will always return 0x0. Near RPC does not seem to support gas estimation for calls.

  • Many fields in Ethereum data structures do not have a direct correspondance to Near data structures. Some attributes of transaction and block objects will be unreliable.

  • Some fields are just unimplemented. For example, tx receipts currently always have a 0x1 status, regardless of the success of the transaction.

  • Some fields are just unimplemented. Always consult implementation in near_to_eth_objects.js. E.g. tx index is constant, and not reliable.

  • Some calls, like eth_getTransactionByBlockHashAndIndex have no sensible correspondance to Near block structure

API Overview

Unless specified, NearProvider returns the values specified in the web3 documentation for each method.

If a method has no direct translation, an Unsupported method error is returned.

Hash Conversions and Equivalents

Near uses base58 while Ethereum uses Keccak. This necessitates the need to convert between the two. With the exception of transaction hashes, Near hashes are converted to Ethereum-compatible hashes when using web3.

Important Format Changes

  • blockHash - a block hash is the hash equivalent of a Near block hash (denoted in base58)

  • transactionHash - a transaction hash is the combination of a Near transaction hash (in base58) concatenanted with the accountId of the transaction's sender, and separated by :

    • <base58TxHash>:<senderAccountId>
  • gas - Gas is denominated in yoctoNEAR

  • value - Transaction values/amounts are denominated in yoctoNEAR

  • to, from, address - Addresses are the EVM hash of a Near AccountId


API - Unsupported Methods

  • web3.eth.getCoinbase
  • web3.eth.isMining
  • web3.eth.getHashrate
  • web3.eth.getBlockUncleCount
  • web3.eth.getUncle
  • web3.eth.getPendingTransactions
  • web3.eth.sign
  • web3.eth.estimateGas
  • web3.eth.getPastLogs
  • web3.eth.getWork
  • web3.eth.submitWork
  • web3.eth.requestAccounts
  • web3.eth.getChainId
  • web3.eth.getNodeInfo
  • web3.eth.getProof

API - Supported Methods

web3.eth.getProtocolVersion

web3.eth.getProtocolVersion([callback])

Returns the Near protocol version of the node.

Returns

Promise returns String: the protocol version.

Differences | Limitations

  • Returns the Near protocol version instead of the Ethereum protocol version

web3.eth.isSyncing

web3.eth.isSyncing

Checks if the node is currently syncing and returns either a syncing object, or false.

Returns

Promise returns Object|Boolean - a syncing object, or false.

  • startingBlock - Unsupported, returns 0x0
  • currentBlock - Returns the latest block height
  • highestBlock - Returns the latest block height
  • knownStates - Unsupported, returns 0x0
  • pulledStates - Unsupported, returns 0x0

Differences | Limitations

  • This will almost always return false
  • If a syncing object does return, the values are generally not useful

web3.eth.getGasPrice

web3.eth.getGasPrice()

Returns the current gas price in yoctoNEAR.

Returns

Promise returns String - Number string of the current gas price in yoctoNEAR.

Differences | Limitations

  • The gas price is returned in yoctoNEAR instead of wei
  • At the moment, the gas price is determined from the most recent block. web3 typically determines the gas price by the last few blocks median gas price.

web3.eth.getAccounts

web3.eth.getAccounts()

Returns a list of accounts the node controls.

Returns

Promise returns Array - An array of addresses controlled by node.

Differences | Limitations

  • Addresses are the EVM hash of a Near AccountId

web3.eth.getBlockNumber

web3.eth.getBlockNumber()

Returns the current block number

Returns

Promise returns Number - The number of the most recent block.


web3.eth.getBalance

web3.eth.getBalance(address)

Returns the balance of an address.

Parameters

  1. String address - The address to get the balance of. This is the EVM address equivalent of a Near AccountId

Returns

Promise returns String - The current balance for the given address in yoctoNEAR.

Differences | Limitations

  • Due to Near RPC limitations, the balance of the address will always be from the latest block.
  • Address is the EVM hash of a Near AccountId

web3.eth.getStorageAt

web3.eth.getStorageAt(address, position)

Get the storage at a specific position of an address.

Parameters

  1. String address - The address to get the storage from. This is the EVM address equivalent of a Near AccountId
  2. Number|String|BN|BigNumber position - the index position of the storage

Returns

Promise returns String - The value in storage at the given position.

Differences | Limitations

  • Due to Near RPC limitations, the balance of the address will always be from the latest block.
  • Address is the EVM hash of a Near AccountId

web3.eth.getCode

web3.eth.getCode(address)

Get the code at a specific address

Parameters

  1. String address - The address to get the code from.

Returns

Promise returns String - The data at given address address.

Differences | Limitations

  • Due to Near RPC limitations, the balance of the address will always be from the latest block.
  • Address is the EVM hash of a Near AccountId

web3.eth.getBlock

web3.eth.getBlock(blockHashOrBlockNumber [, returnTransactionObjects])

Returns a block matching the block number or block hash

Parameters

  1. String|Number|BN|BigNumber - The block number or block hash. Or the string 'genesis', 'latest', 'earliest', or 'pending'
  2. Boolean - (optional, default false) If specified true, the returned block will contain all transactions as objects. By default it is false so, there is no need to explictly specify false. And, if false it will only contain the transaction hashes.

Returns

Promise returns Object - The block object

  • number - The block number
  • hash - Hash equivalent of the base58 Near block hash
  • parentHash - Hash equivalent of the base58 Near block's parent block hash
  • nonce - Always returns null. This is typically the hash of the generated proof-of-work. There is no equivalent concept in Near.
  • transactionsRoot - Always returns 0x0000.... Since transactions are on chunks and chunks are on block, there is no equivalent of a transaction trie of the block
  • size - Returns the weight of the block
  • gasLimit - The maximum gas allowed in this block. Returned in yoctoNEAR
  • gasUsed - The total used gas by all chunks in this block. A chunk may have a transaction, but that transaction may be processed in a different chunk.
  • timestamp - The unix timestamp for when the block was collated
  • transactions - Array of transaction objects, or the 32 byte transaction hashes equivalent of the base58 Near transaction hashes.
  • sha3Uncles - Unsupported, undefined/null value returned
  • logsBloom - Unsupported, undefined/null value returned
  • stateRoot - Unsupported, undefined/null value returned
  • miner - Unsupported, undefined/null value returned
  • difficulty - Unsupported, undefined/null value returned
  • totalDifficulty - Unsupported, undefined/null value returned
  • extraData - Unsupported, undefined/null value returned
  • uncles - Unsupported, undefined/null value returned

Differences | Limitations

  • Passing through 'genesis' or 'earliest' will return block 0
  • Passing through 'latest' or 'pending' will return the latest block. There is no concept of pending blocks.
  • See Important Format Changes for information on hash, gas, transactions

web3.eth.getBlockTransactionCount

web3.eth.getBlockTransactionCount(blockHashOrBlockNumber)

Returns the number of transactions in a given block.

Parameters

  1. {String|Number|BN|BigNumber} - The block number or block hash. Or the string 'genesis', 'latest', 'earliest', or 'pending'

Returns

Promise returns Number - The number of transactions in the given block.

Differences | Limitations

  • Blocks have chunks and chunks have transactions; all the transactions are collected from a block's chunks and counted. Conceptually this is the same thing, but note that transactions do not actually reside in blocks.

web3.eth.getTransaction

web3.eth.getTransaction(transactionHash)

Returns a transaction matching the given transaction hash.

Parameters

  1. String transactionHash - the transaction hash

Returns

Promise returns Object - A transaction object

  • hash - Hash of the transaction <nearTxHash>:<accountId> (transaction's sender's accountId)
  • nonce - The number of transactions made by the sender prior to this one
  • blockHash - hash equivalent of the block where this transaction was in.
  • blockNumber - Block number where this transaction was in
  • transactionIndex - integer of the transactions index position in the block.
  • from - EVM Address of the sender
  • to - EVM address of the receiver
  • value - Value transfered in yoctoNEAR
  • gasPrice - Gas price set by the block in yoctoNEAR
  • gas - Gas consumed by the sender in yoctoNEAR
  • input - Unsupported, null value provided

Differences | Limitations

  • Due to the Near protocol, getting a transaction's status requires knowing both the transaction hash and the Near AccountId of the transaction's signer. To allow for this, transaction hashes in NearProvider are the base58 transaction hashes concatenated with the signer_id of the transaction, and separated with a :.

    Example:

    // A Near transaction hash (base58)
    const nearTxHash = 'ByGDjvYxVZDxv69c86tFCFDRnJqK4zvj9uz4QVR4bH4P';
    
    // A Near AccountId. In particular, the AccountId of the transaction's signer
    const signerId = 'test.near'
    
    // Concatenate and separate with ':'
    const txHash = `${nearTxHash}:${signerId};
    
    console.log(txHash);
    
    // ByGDjvYxVZDxv69c86tFCFDRnJqK4zvj9uz4QVR4bH4P:test.near
    
  • See Important Format Changes for additional information.


web3.eth.getTransactionFromBlock

web3.eth.getTransactionFromBlock(hashStringOrNumber, indexNumber)

Returns a transaction based on a block hash or number and the transaction's index position.

Parameters

  1. {String|Number|BN|BigNumber} hashStringOrNumber The block number or block hash. Or the string 'genesis', 'latest', 'earliest', or 'pending'
  2. {Number} indexNumber - The transaction's index position

Returns

Promise returns Object - A transaction object. See web3.eth.getTransaction.

Differences | Limitations

See web3.eth.getTransaction.


web3.eth.getTransactionReceipt

web3.eth.getTransactionReceipt(hash)

Returns the receipt of a transaction by transaction hash.

Parameters

  1. String transactionHash - the transaction hash. See web3.eth.getTransaction.

Returns

Promise returns Object - A transaction receipt object

  • status - Returns true if the transaction was successful, false if the EVM reverted the transaction
  • blockHash Hash of the block where this transaction was in.
  • blockNumber - Block number where this transaction was in.
  • transactionHash - Hash of the transaction.
  • transactionIndex - Integer of the transactions index position in the block.
  • from - Address of the sender.
  • to - Address of the receiver. null when its a contract creation transaction.
  • contractAddress - The contract address created, if the transaction was a contract creation, otherwise null.
  • cumulativeGasUsed - The total amount of gas used when this transaction was executed in the block.
  • gasUsed- The amount of gas used by this specific transaction alone.
  • logs - Array of log objects, which this transaction generated.

Differences | Limitations

See web3.eth.getTransaction.


web3.eth.getTransactionCount

web3.eth.getTransactionCount(address)

Get the numbers of transactions sent from this address.

Parameters

  1. String address - The address to get the numbers of transactions from. Address is the EVM address of a Near AccountId

Returns

Promise returns Number - The number of transactions sent from the given address

Differences | Limitations

  • Specifically, returns the nonce of transactions sent from the address. Near will only return the total transactions; selecting a block is not supported.

web3.eth.sendTransaction

web3.eth.sendTransaction(transactionObject

Sends a transaction to the network.

Parameters

  1. Object - the transaction object to send:

    • to - String: EVM destination address
    • value - Number|String|BN|BigNumber: amount of yoctoNEAR to attach
    • gas - Number: amount of gas to use for the transaction in yoctoNEAR
    • data - String: the encoded call data

Returns

Returns the transactionHash of the transaction: <base58TxHash>:<accountId>

Differences | Limitations

  • The sender is the default accountId. At this time, another account cannot be specified.
  • All other optional properties on the transaction object are unsupported

web3.eth.sendSignedTransaction

Unsupported at the moment, always returns 0x0.


web3.eth.call (in progress)

web3.eth.signTransaction(transactionObject)

Executes a new message call immediately without creating a transaction on the block chain.

Parameters

  1. Object - A transaction object, see web3.eth.sendTransaction, with the difference that only the to field is required.

Returns

Promise returns String: The returned data of the call, e.g. a smart contract functions return value.

Differences | Limitations

  • Due to Near RPC limitations, this will always be called on the latest block.

To Do

  • Update hardcoded transactionIndex
  • Make sure all errors are handled
  • Expose utils.nearAccountToEvmAddress, otherwise users will not be able to pass through the EVM Address equivalent
  • Expose conversion utils like base58ToHex, hexToBase58
  • Add documentation about accessing provider methods (point to Near docs, explain relevant methods)