Passing a js var into a solidity function - javascript

Wrote a function in solidity which is like this,
function AddData(uint _index, string _projectName, string _devAddress, string _developer) public {
Datas[_index] = Data(_index, 0, _projectName, _devAddress, _developer);
}
Note that this is just a fragment of the whole solidity code. In js, i'm trying to pass variables into the functions but doesnt seem to be working. I assume it's the js variables unable to pass into solidity string variables.
counterDB.AddData(id_db, projectName, devAddress, developer, function (err, result) {
if (err) {
console.log('Error: ' + err);
}
else {
console.log(result);
}
});
The variables passed in are data i pulled out from the database to pass into the smart contract. I checked every data has been pulled in properly but i cant pass the data into the function. Am i missing a function to convert the var into string?

Are you using web3 v1.0 ? Have you tried to pass the function like this:
var yourContract = new web3.eth.Contract(ABI, contractAddress);
const contractFunction = yourContract.methods.AddData(id_db, projectName, devAddress, developer);
const functionBytes = contractFunction.encodeABI();
const rawTx = {
gasLimit: web3.utils.toHex(200000),
to: contractAddress,
from: addressFrom,
data: functionBytes
};
web3.eth.accounts.signTransaction(rawTx, privateKey)
.then(RLPencodedTx => {
web3.eth.sendSignedTransaction(RLPencodedTx['rawTransaction'])
.on('error', error => { callback(null, error) })
.on('receipt', receipt => { callback(receipt) });
})
Keep in mind, that you have to decrypt the private key if you are using the json export of it:
var path = process.cwd();
const exportedAccountString = fs.readFileSync(path + '/your_key_file.json').toString();
const decrypted = web3.eth.accounts.decrypt(exportedAccountString, 'YourPasswordHere...');
const privateKey = decrypted.privateKey;

Related

Making a distinction between file not present and access denied while accessing s3 object via Javascript

I have inherited the following code. This is part of CICD pipeline. It tries to get an object called "changes" from a bucket and does something with it. If it is able to grab the object, it sends a success message back to pipeline. If it fails to grab the file for whatever reason, it sends a failure message back to codepipeline.
This "changes" file is made in previous step of the codepipeline. However, sometimes it is valid for this file NOT to exist (i.e. when there IS no change).
Currently, the following code makes no distinction if file simply does not exist OR some reason code failed to get it (access denied etc.)
Desired:
I would like to send a success message back to codepipeline if file is simply not there.
If there is access issue , then the current outcome of "failure' would still be valid.
Any help is greatly appreciated. Unfortunately I am not good enough with Javascript to have any ideas to try.
RELEVANT PARTS OF THE CODE
const AWS = require("aws-sdk");
const s3 = new AWS.S3();
const lambda = new AWS.Lambda();
const codePipeline = new AWS.CodePipeline();
// GET THESE FROM ENV Variables
const {
API_SOURCE_S3_BUCKET: s3Bucket,
ENV: env
} = process.env;
const jobSuccess = (CodePipeline, params) => {
return new Promise((resolve, reject) => {
CodePipeline.putJobSuccessResult(params, (err, data) => {
if (err) { reject(err); }
else { resolve(data); }
});
});
};
const jobFailure = (CodePipeline, params) => {
return new Promise((resolve, reject) => {
CodePipeline.putJobFailureResult(params, (err, data) => {
if (err) { reject(err); }
else { resolve(data); }
});
});
};
// MAIN CALLER FUNCTION. STARTING POINT
exports.handler = async (event, context, callback) => {
try {
// WHAT IS IN changes file in S3
let changesFile = await getObject(s3, s3Bucket, `lambda/${version}/changes`);
let changes = changesFile.trim().split("\n");
console.log("List of Changes");
console.log(changes);
let params = { jobId };
let jobSuccessResponse = await jobSuccess(codePipeline, params);
context.succeed("Job Success");
}
catch (exception) {
let message = "Job Failure (General)";
let failureParams = {
jobId,
failureDetails: {
message: JSON.stringify(message),
type: "JobFailed",
externalExecutionId: context.invokeid
}
};
let jobFailureResponse = await jobFailure(codePipeline, failureParams);
console.log(message, exception);
context.fail(`${message}: ${exception}`);
}
};
S3 should return an error code in the exception:
The ones you care about are below:
AccessDenied - Access Denied
NoSuchKey - The specified key does not exist.
So in your catch block you should be able to validate exception.code to check if it matches one of these 2.

Adding multiple BigQuery JSON credential files in Node project

I've been working on a Node project that involves fetching some data from BigQuery. Everything has been fine so far; I have my credential.json file (from BigQuery) and the project works as expected.
However, I want to implement a new feature in the project and this would involve fetching another set of data from BigQuery. I have an entirely different credential.json file for this new dataset. My project seems to recognize only the initial credential.json file I had (I named them differently though).
Here's a snippet of how I linked my first credential.json file:
function createCredentials(){
try{
const encodedCredentials = process.env.GOOGLE_AUTH_KEY;
if (typeof encodedCredentials === 'string' && encodedCredentials.length > 0) {
const google_auth = atob(encodedCredentials);
if (!fs.existsSync('credentials.json')) {
fs.writeFile("credentials.json", google_auth, function (err, google_auth) {
if (err) console.log(err);
console.log("Successfully Written to File.");
});
}
}
}
catch (error){
logger.warn(`Ensure that the environment variable for GOOGLE_AUTH_KEY is set correctly: full errors is given here: ${error.message}`)
process.kill(process.pid, 'SIGTERM')
}
}
Is there a way to fuse my two credential.json files together? If not, how can I separately declare which credential.json file to use?
If not, how can I separately declare which credential.json file to use?
What I would do I would create a function which is the exit point to BigQuery and pass an identifier to your function which credential to generate, This credential will then be used when calling BigQuery.
The below code assume you changed this
function createCredentials(){
try{
const encodedCredentials = process.env.GOOGLE_AUTH_KEY;
To this:
function createCredentials(auth){
try{
const encodedCredentials = auth;
And you can use it like this
import BigQuery from '#google-cloud/bigquery';
import {GoogApi} from "../apiManager" //Private code to get Token from client DB
if (!global._babelPolyfill) {
var a = require("babel-polyfill")
}
describe('Check routing', async () => {
it('Test stack ', async (done, auth) => {
//Fetch client Auth from local Database
//Replace the 2 value below with real values
const tableName = "myTest";
const dataset = "myDataset";
try {
const bigquery = new BigQuery({
projectId: `myProject`,
keyFilename: this.createCredentials(auth)
});
await bigquery.createDataset(dataset)
.then(
args => {
console.log(`Create dataset, result is: ${args}`)
})
.catch(err => {
console.log(`Error in the process: ${err.message}`)
})
} catch (err) {
console.log("err", err)
}
})
})

Passing req.params around in Node MVC

I'm trying to figure out how to pass req.params around using Express in the context of MVC.
I know how to properly reference req.params but when I split my app.js up into models and controllers I'm quite lost.
Code for reference:
routes.js
app.get('/category/:category', descriptor.getSingleCategory)
model.js
let getSingleCat = (cb) => {
let queryString = 'SELECT * FROM categories WHERE category_id = $1'
let queryValue = [req.params.category]
db.query(queryString, queryValue, cb)
}
controller.js
const getSingleCategory = (req, response) => {
console.log(req.params.category);
db.desc.getSingleCat((err, queryRes) => {
if (err) {
//render something went wrong
response.send('something went wrong')
} else {
response.send(queryRes.rows)
}
})
}
I've checked all requires and they are working correctly. Is there a vanilla way of passing req.params around without using middleware?
The only way to use the req.params in the model, is by sending it as parameters as the following example:
model.js
let getSingleCat = (params, cb) => {
let queryString = 'SELECT * FROM categories WHERE category_id = $1'
let queryValue = params.category
db.query(queryString, queryValue, cb)
}
controller.js
const getSingleCategory = (req, response) => {
console.log(req.params.category);
db.desc.getSingleCat(req.params, (err, queryRes) => {
if (err) {
//render something went wrong
response.send('something went wrong')
} else {
response.send(queryRes.rows)
}
})
}
You can't use global vars, so this is the only way to do it. Also, this variable (req) can only be accessed in the functions bound to an endpoint that will receive an actual request.

Google Cloud Functions - access to key's value

I'm trying to return a value out of an array of values I get from querying Datastore.
results[0] have this content: {"prod_name":"Muffin","prod_price":3.99}.
I'd like to return via res.send only: 3.99
I've tried results[0].prod_price, or results[0]['prod_price'], I have tried saving results[0] as variable and trying to return prod_price, but nothing works.
Any help is appreciated.
My code is here:
const Datastore = require('#google-cloud/datastore');
const Storage = require('#google-cloud/storage');
// Instantiates a client
const datastore = Datastore();
const storage = new Storage();
exports.getprice = function getprice (req, res) {
const kind = datastore.createQuery("Dialogflow");
const filter = kind.filter("prod_name", req.body.queryResult.parameters['bakery_items']);
return query = datastore.runQuery(kind)
.then( (results) => {
const entities = results[0];
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ "fulfillmentText": entities}));
})
.catch((err) => {
console.error(err);
res.status(500).send(err);
return Promise.reject(err);
});
};
I got it.
Actually I kept results instead of forcing results[0], and realized the output had an extra array, so to access the value, I had to do: results[0][0]['prod_price']
Thanks to JavaScript console.

Sending an AlchemyData News query using Node.js (watson-developer-cloud module)

I'm currently working with Node.js using the watson-developer-cloud Node.js SDK and I'm having problems when sending a query that includes an entity.
This is my code:
// require watson's node sdk and fs
var watson = require('watson-developer-cloud');
var fs = require('fs');
// Define output file
var outputJSONFile = '/home/vagrant/Desktop/node/dir/data.json';
// Create alchemy_data_news object using our api_key
var alchemy_data_news = watson.alchemy_data_news({
api_key: ''
});
// Define params for the query and what values to return
// Accepted returne values:
// docs.alchemyapi.com/v1.0/docs/full-list-of-supported-news-api-fields
var params = {
start: 'now-1m',
end: 'now',
count: 2,
qs: ['q.enriched.url.enrichedTitle.entities.entity.text=apple'],
return: ['enriched.url.url,enriched.url.title']
};
// Call getNews method and return json
alchemy_data_news.getNews(params, function (err, news) {
if (err) {
console.log('error:', err);
} else {
fs.writeFile(outputJSONFile, JSON.stringify(news, null, 2), function(err) {
if (err) {
console.log('WriteFile Error:', err);
} else {
console.log("JSON saved to " + outputJSONFile);
}
});
}
});
I'm still trying to figure out how to send the entities parameters using the params object.
While digging up through some code I came across qs so I have been using that to test but I haven't had success at all.
Any suggestions are greatly appreciated.
P.S: I'm trying to pass:
q.enriched.url.enrichedTitle.entities.entity.text=apple
q.enriched.url.enrichedTitle.entities.entity.type=company
If you look at the node-sdk source code for AlchemyDataNews, you will see that the top level parameters are being sent as query strings.
Then params map should be:
var params = {
start: 'now-1m',
end: 'now',
count: 2,
return: ['enriched.url.url,enriched.url.title'],
// fields here
'q.enriched.url.enrichedTitle.entities.entity.text': 'apple',
'q.enriched.url.enrichedTitle.entities.entity.type': 'company'
};

Categories