Skip to content
This repository has been archived by the owner on Oct 4, 2024. It is now read-only.

Adding support for EVM view and function calls #517

Merged
merged 13 commits into from
Nov 17, 2020
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions bin/near-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ yargs // eslint-disable-line
.middleware(require('../middleware/print-options'))
.middleware(require('../middleware/key-store'))
.middleware(require('../middleware/ledger'))
.middleware(require('../middleware/abi'))
.middleware(require('../middleware/seed-phrase'))
.command(require('../commands/create-account').createAccountCommand)
.command(require('../commands/create-account').createAccountCommandDeprecated)
Expand All @@ -244,6 +245,8 @@ yargs // eslint-disable-line
.command(require('../commands/delete-key'))
.command(require('../commands/validators'))
.command(require('../commands/proposals'))
.command(require('../commands/evm-call'))
.command(require('../commands/evm-view'))
.config(config)
.alias({
'accountId': ['account_id'],
Expand Down
56 changes: 56 additions & 0 deletions commands/evm-call.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const exitOnError = require('../utils/exit-on-error');
const web3 = require('web3');
const { NearProvider, utils } = require('near-web3-provider');
const assert = require('assert');

module.exports = {
command: 'evm-call <evmAccount> <contractName> <methodName> [args]',
mikedotexe marked this conversation as resolved.
Show resolved Hide resolved
desc: 'Schedule call inside EVM machine',
builder: (yargs) => yargs
.option('gas', {
desc: 'Max amount of NEAR gas this call can use',
type: 'string',
default: '100000000000000'
})
.option('amount', {
desc: 'Number of tokens to attach',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In NEAR or yoctoNEAR

type: 'string',
default: '0'
})
.option('args', {
desc: 'Arguments to the contract call, in JSON format (e.g. \'[1, "str"]\') based on contract ABI',
type: 'string',
default: null
})
.option('accountId', {
required: true,
desc: 'Unique identifier for the account that will be used to sign this call',
type: 'string',
})
.option('abi', {
required: true,
desc: 'Path to ABI for given contract',
type: 'string',
}),
handler: exitOnError(scheduleEVMFunctionCall)
};

async function scheduleEVMFunctionCall(options) {
const args = JSON.parse(options.args || '[]');
console.log(`Scheduling a call inside ${options.evmAccount} EVM:`);
console.log(`${options.contractName}.${options.methodName}()` +
(options.amount && options.amount !== '0' ? ` with attached ${options.amount} NEAR` : ''));
console.log(' with args', args);
const web = new web3();
web.setProvider(new NearProvider({
nodeUrl: options.nodeUrl,
// TODO: make sure near-api-js has the same version between near-web3-provider.
// keyStore: options.keyStore,
masterAccountId: options.accountId,
networkId: options.networkId,
evmAccountId: options.evmAccount,
}));
const contract = new web.eth.Contract(options.abi, options.contractName);
assert(options.methodName in contract.methods, `${options.methodName} is not present in ABI`);
await contract.methods[options.methodName](...args).send({ from: utils.nearAccountToEvmAddress(options.accountId) });
}
42 changes: 42 additions & 0 deletions commands/evm-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const exitOnError = require('../utils/exit-on-error');
const web3 = require('web3');
const { NearProvider, utils } = require('near-web3-provider');
const assert = require('assert');

module.exports = {
command: 'evm-view <evmAccount> <contractName> <methodName> [args]',
desc: 'View call inside EVM machine',
builder: (yargs) => yargs
.option('args', {
desc: 'Arguments to the contract call, in JSON format (e.g. \'[1, "str"]\') based on contract ABI',
type: 'string',
default: null
})
.option('accountId', {
required: true,
desc: 'Unique identifier for the account that will be used to sign this call',
type: 'string',
})
.option('abi', {
desc: 'Path to ABI for given contract',
type: 'string',
}),
handler: exitOnError(scheduleEVMFunctionView)
};

async function scheduleEVMFunctionView(options) {
const web = new web3();
web.setProvider(new NearProvider({
nodeUrl: options.nodeUrl,
// TODO: make sure near-api-js has the same version between near-web3-provider.
// keyStore: options.keyStore,
masterAccountId: options.accountId,
networkId: options.networkId,
evmAccountId: options.evmAccount,
}));
const contract = new web.eth.Contract(options.abi, options.contractName);
const args = JSON.parse(options.args || '[]');
assert(options.methodName in contract.methods, `${options.methodName} is not present in ABI`);
const result = await contract.methods[options.methodName](...args).call({ from: utils.nearAccountToEvmAddress(options.accountId) });
console.log(result);
}
11 changes: 11 additions & 0 deletions middleware/abi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const fs = require('fs');

async function loadAbi(abiPath) {
return JSON.parse(fs.readFileSync(abiPath)).abi;
}

module.exports = async function parseAbi(options) {
if (options.abi) {
options.abi = await loadAbi(options.abi);
}
};
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"jest-environment-node": "^26.0.0",
"mixpanel": "^0.13.0",
"ncp": "^2.0.0",
"near-web3-provider": "https://github.com/near/near-web3-provider",
"near-api-js": "^0.30.0",
"near-seed-phrase": "^0.1.0",
"open": "^7.0.1",
Expand All @@ -51,6 +52,7 @@
"update-notifier": "^5.0.0",
"uuid": "^8.0.0",
"v8flags": "^3.1.3",
"web3": "^1.2.11",
"yargs": "^16.0.3"
},
"optionalDependencies": {
Expand Down
Loading