How to get pending transactions in ethereum using web3? - ethereum

I need to calculate the nonce for successive transactions using web3js in Ethereum, but getTransactionCount does not return pending transactions.
Is there a way to get all transactions including both pending and completed transactions using web3js? If not web3js, is there some other way to do that??

using web3js 1.0 you can use getPendingTransactions
web3.eth.getPendingTransactions().then(console.log);
> [
{
hash: '0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b',
nonce: 2,
blockHash: '0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46',
blockNumber: 3,
transactionIndex: 0,
from: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b',
to: '0x6295ee1b4f6dd65047762f924ecd367c17eabf8f',
value: '123450000000000000',
gas: 314159,
gasPrice: '2000000000000',
input: '0x57cb2fc4'
v: '0x3d',
r: '0xaabc9ddafffb2ae0bac4107697547d22d9383667d9e97f5409dd6881ce08f13f',
s: '0x69e43116be8f842dcd4a0b2f760043737a59534430b762317db21d9ac8c5034'
},....,

Did you try using web3.eth.filter?
Following code should work. (unable to test myself at the moment)
var options = {
fromBlock: "pending",
toBlock: "latest",
address: "0xabc123...",
}
web3.eth.filter(options, (error, result) => {
if (!error)
console.log(result);
});

This is a known issue# 1741, maybe you can better wait for the transactions to get cleared as a work around.

I made a script in python using web3.py to retrieve pending transactions! it's on my GitHub: https://github.com/soos3d/Retrive-and-display-pending-transactions-Web3.py. Feel free to check it out! But the main code to do that is this.
# retrive pending transactions hash
pending_tx_filter = web3.eth.filter('pending')
pending_tx = pending_tx_filter.get_new_entries()
then you can loop through the "pending_tx" variable and extract the transactions hash.

Related

Sending data to CloudWatch using the AWS-SDK

I want to write data to CloudWatch using the AWS-SDK (or whatever may work).
I see this:
The only method that looks remotely like publishing data to CloudWatch is the putMetricData method..but it's hard to find an example of using this.
Does anyone know how to publish data to CloudWatch?
When I call this:
cw.putMetricData({
Namespace: 'ec2-memory-usage',
MetricData: [{
MetricName:'first',
Timestamp: new Date()
}]
}, (err, result) => {
console.log({err, result});
});
I get this error:
{ err:
{ InvalidParameterCombination: At least one of the parameters must be specified.
at Request.extractError (/Users/alex/codes/interos/jenkins-jobs/jobs/check-memory-ec2-instances/node_modules/aws-sdk/lib/protocol/query.js:50:29)
at Request.callListeners (/Users/alex/codes/interos/jenkins-jobs/jobs/check-memory-ec2-instances/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/Users/alex/codes/interos/jenkins-jobs/jobs/check-memory-ec2-instances/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/Users/alex/codes/interos/jenkins-jobs/jobs/check-memory-ec2-instances/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/Users/alex/codes/interos/jenkins-jobs/jobs/check-memory-ec2-instances/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/Users/alex/codes/interos/jenkins-jobs/jobs/check-memory-ec2-instances/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /Users/alex/codes/interos/jenkins-jobs/jobs/check-memory-ec2-instances/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/Users/alex/codes/interos/jenkins-jobs/jobs/check-memory-ec2-instances/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/Users/alex/codes/interos/jenkins-jobs/jobs/check-memory-ec2-instances/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/Users/alex/codes/interos/jenkins-jobs/jobs/check-memory-ec2-instances/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
message: 'At least one of the parameters must be specified.',
code: 'InvalidParameterCombination',
time: 2019-07-08T19:41:41.191Z,
requestId: '688a4ff3-a1b8-11e9-967e-431915ff0070',
statusCode: 400,
retryable: false,
retryDelay: 7.89360948163893 },
result: null }
You're getting this error because you're not specifying any metric data. You're only setting the metric name and the timestamp. You also need to send some values for the metric.
Let's say your application is measuring the latency of requests and you observed 5 requests, with latencies 100ms, 500ms, 200ms, 200ms and 400ms. You have few options for getting this data into CloudWatch (hence the At least one of the parameters must be specified. error).
You can publish these 5 values one at a time by setting the Value within the metric data object. This is the simplest way to do it. CloudWatch does all the aggregation for you and you get percentiles on your metrics. I would not recommended this approach if you need to publish many observations. This option will result in the most requests made to CloudWatch, which may result in a big bill or throttling from CloudWatch side if you start publishing too many observations.
For example:
MetricData: [{
MetricName:'first',
Timestamp: new Date(),
Value: 100
}]
You can aggregate the data yourself and construct and publish the StatisticValues. This is more complex on your end, but results in the fewest requests to CloudWatch. You can aggregate for a minute for example and execute 1 put per metric every minute. This will not give you percentiles (since you're aggregating data on your end, CloudWatch doesn't know the exact values you observed). I would recommend this if you do not need percentiles.
For example:
MetricData: [{
MetricName:'first',
Timestamp: new Date(),
StatisticValues: {
Maximum: 500,
Minimum: 100,
SampleCount: 5,
Sum: 1400
}
}]
You can count the observations and publish Values and Counts. This is kinda the best of both worlds. There is some complexity on your end, but counting is arguably easier than aggregating into StatisticValues. You're still sending every observation so CloudWatch will do the aggregation for you, so you'll get percentiles. The format also allows more data to be sent than in the option 1. I would recommend this if you need percentiles.
For example:
MetricData: [{
MetricName:'first',
Timestamp: new Date(),
Values: [100, 200, 400, 500],
Counts: [1, 2, 1, 1]
}]
See here for more details for each option: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CloudWatch.html#putMetricData-property

Consuming MySql Procedure out parameter which contains # in node js

I'm having issues with consuming Out Parameters from mySql in node JS when they contain #, I've searched for similar question but can't see any answers to my specific question:
Here's the procedure (not my code)
CREATE PROCEDURE `getuser`(IN `p_googleemail` varchar(64),
out `p_userjson` json)
SET #'p_userJSON' =
(
SELECT json_object('email', USER.email, 'lastName', USER.lastname, 'firstName', USER.firstname )
FROM test.USER
WHERE email = p_googleemail);
select #p_userJSON;
end
Here is a snippet of my Node Code:
/* GET users listing. */
router.get('/', function(req, res, next) {
getConnection(function(err, con) {
googleEmail ='test#gmail.com';
que = 'CALL test.getUser(?, #p_userJSON);';
con.query(que,[googleEmail], function(err, results) {
if (err) throw err;
con.release();
res.send(results);
});
});
});
This is the response:
[
[{
"#p_userJSON": "{\"email\": \"test#gmail.com\", \"lastName\": \"test\", \"firstName\": \"test\"}"
}],
{
"fieldCount": 0,
"affectedRows": 0,
"insertId": 0,
"serverStatus": 34,
"warningCount": 1,
"message": "",
"protocol41": true,
"changedRows": 0
}
]
How do I return the results from #p_userJSON as part of my rest service? I understand I'll have to unescape the json from the out param but I can't even return the #p_userJSON value.
Many thanks!
Edit:
My hack to get around the issue for the minute, this not the full code as got some error handling if there are no results (probably a better way but I've only been using js for a few weeks)
var datapackstr = JSON.stringify(results[0]);
var datapack = JSON.parse(JSON.parse(datapackstr.substring((datapackstr.lastIndexOf('#p_userJSON') + 12) + 1).slice(0, -2)));
Even though this thread is 6 years old I came across basically the same issue with the #. The problem is with the JSON string that's being returned and JSON.parse's ability to deal with the stirngs in #p_userJSON.
The below JSON string works as expected.
var result = '[[{"#p_userJSON": "{\\\"email\\\": \\\"test#gmail.com\\\", \\\"lastName\\\": \\\"test\\\", \\\"firstName\\\": \\\"test\\\"}"}],{"fieldCount": 0,"affectedRows": 0,"insertId": 0,"serverStatus": 34,"warningCount": 1,"message": "","protocol41": true,"changedRows": 0}]';
var res = JSON.parse(result);
console.log(res[0][0]['#p_userJSON']);
You can see a working example in a node fiddle here.
I did need to make some manual changes to the JSON. Remember that JSON.parse won't throw an error when it fails to return an actual JSON object it will simply return an object for each character in the input string.
You can find more info about the JSON.parse function here.

Node.js JSON extract certain data

I'm trying to get certain data from a json link:
bittrex.com/api/v1.1/public/getticker?market=BTC-DRS
in my node IRC bot using:
https://www.npmjs.org/package/node.bittrex.api
Part of the code:
var url = ('https://bittrex.com/api/v1.1/public/getticker?market=BTC-DRS');
bittrex.options({
'apikey' : settings.ticker.apikey,
'apisecret' : settings.ticker.secretkey,
'stream' : false,
'verbose' : false,
'cleartext' : true,
});
case 'ticker':
var user = from.toLowerCase();
bittrex.sendCustomRequest(url, function(ticker, err) {
if(err) {
winston.error('Error in !ticker command.', err);
client.say(channel, settings.messages.error.expand({name: from}));
return;
}
winston.info('Fetched Price From BitTrex', ticker);
client.say(channel, settings.messages.ticker.expand({name: user, price: ticker}));
});
break;
It works but outputs in IRC
[1:21am] <nrpatten> !ticker
[1:21am] <DRSTipbot> nrpatten The current DRS price at BitTrex {"success":true,"message":"","result":{"Bid":0.00000155,"Ask":0.00000164,"Last":0.00000155}}
I have used a couple of things to get it to show only "Last" from the reply but i keep getting errors.
Or get certain data from https://bittrex.com/api/v1.1/public/getmarketsummaries
Like any info i want from:
{"MarketName":"BTC-DRS","High":0.00000161,"Low":0.00000063,"Volume":280917.11022708,"Last":0.00000155,"BaseVolume":0.33696054,"TimeStamp":"2014-10-04T15:14:19.66","Bid":0.00000155,"Ask":0.00000164,"OpenBuyOrders":33,"OpenSellOrders":138,"PrevDay":0.00000090,"Created":"2014-06-18T04:35:38.437"}
Thanks for any help
Assuming you've parsed the JSON (e.g. via JSON.parse(str);), you just use whatever property name you want to get at. For example:
var info = JSON.parse('{"MarketName":"BTC-DRS","High":0.00000161,"Low":0.00000063,"Volume":280917.11022708,"Last":0.00000155,"BaseVolume":0.33696054,"TimeStamp":"2014-10-04T15:14:19.66","Bid":0.00000155,"Ask":0.00000164,"OpenBuyOrders":33,"OpenSellOrders":138,"PrevDay":0.00000090,"Created":"2014-06-18T04:35:38.437"}');
console.log(info.Bid);
Also, on an unrelated matter, typically callback parameters follow the error-first format (e.g. (err, result) instead of (result, err)) in order to be consistent with node core and most other modules on npm.

Last Fm API returns nothing with specific time period

I'm using the last fm api to get data from a user but when using the User.getTopTracks method with the time period 1month, it returns nothing:
{
toptracks: {
#text: " ",
user: "RJ",
type: "1month",
page: "",
perPage: "",
totalPages: "",
total: "0"
}
}
This error does not occur when using similar methods (e.g. User.getTopAlbums)
This is a bug in the Last.fm API.
The issue used to exist for getTopArtists as well. It has been fixed for the artists call, but not for getTopTracks.
My solution is to use 3month when the user selects 1month. If I have time I will update the UI to work around this issue.

Iterating through couchbase keys without a view

In couchbase, I was wondering if there was a way - WITHOUT using a view - to iterate through database keys. The admin interface appears to do this, but maybe its doing something special. What I'd like to is make a call like this to retrieve an array of keys:
$result = $cb->get("KEY_ALBERT", "KEY_FRED");
having the result be an array [KEY_ALEX, KEY_BOB, KEY_DOGBERT]
Again, I don't want to use a view unless there's no alternative. Doesn't look like its possible, but since the "view documents" in the admin appears to do this, I thought i'd double-check. I'm using the php interface if that matters.
Based on your comments, the only way is to create a simple view that emit only the id as par of the key:
function(doc, meta) {
emit( meta.id );
}
With this view you will be able to create query with the various options you need :
- pagination, range, ...
Note: you talk about the Administration Console, the console use an "internal view" that is similar to what I have written above (but not optimized)
I don't know about how couchbase admin works, but there are two options. First option is to store your docs as linked list, one doc have property (key) that points to another doc.
docs = [
{
id: "doc_C",
data: "somedata",
prev: "doc_B",
next: "doc_D"
},
{
id: "doc_D",
data: "somedata",
prev: "doc_C",
next: "doc_E"
}
]
The second approach is to use sequential id. You should have one doc that contain sequence and increment it on each add. It would be something like this:
docs = [
{
id: "doc_1",
data: "somedata"
},
{
id: "doc_2",
data: "somedata"
}
...
]
In this way you can do "range requests". To do this you form array of keys on server side:
[doc_1, doc_2 .... doc_N]and execute multiget query. Here is also a link to another example
The couchbase PHP sdk does support multiget requests. For a list of keys it will return an array of documents.
getMulti(array $ids, array $cas, int $flags) : array
http://www.couchbase.com/autodocs/couchbase-php-client-1.1.5/classes/Couchbase.html#method_getMulti