Get token transfer detail from transaction hash with web3js - ethereum

With web3js, how do you figure out that there was 40000 tokens transfer from the transaction's hash?

There's a very good blog post on Medium using the exact method you're interested in.
(Stealing from the post):
Retrieve the input data from web3.eth.getTransaction() This will return the hex data for the function and parameters sent in the transaction. It will look something like 0xa9059cbb0000000000000000000000007adee867ea91533879d083dd47ea81f0eee3a37e000000000000000000000000000000000000000000000000d02ab486cedbffff.
The first 32 bits (0xa9059cbb) is the sha3 encoded text of the function signature.
Every 256 bit block after that is an argument passed in.
After parsing out the block corresponding to the number of tokens in the parameter list, use web3.utils to convert to decimal.

I will try to show an example how you do this:
lets take this Tx:
0xa543a3a7b6498bc9aec6989d99228be07855cdd23cfbf491489e8d4088b4a94c
This is Tx to a contract that send some amount of token to address
The received data from web3.eth.getTransaction() input:
0xa9059cbb00000000000000000000000092e707288dc221d864cf4a8c710c143e97225d7d000000000000000000000000000000000000000000000059f37b9220158a8000
Now the first 34 bits represent text of the function signature (0xa9059cbb)
The next 256 bit block represent the address we want send the token to:
00000000000000000000000092e707288dc221d864cf4a8c710c143e97225d7d
The second block represent the amount (in hex) of tokens that were sent to the address:
000000000000000000000000000000000000000000000059f37b9220158a8000
We will convert the hex to decimal with any conversion function or with this web site:
https://www.rapidtables.com/convert/number/hex-to-decimal.html
we will see that after the conversion we get 1659305000000000000000
it the number of token that sent to the address.
I hope it help

Ethereum smart contract transaction input data decoder
Uses ethereumjs-abi for decoding.
https://github.com/miguelmota/ethereum-input-data-decoder

just use web3.eth.getTransaction(transaction_address)
let transaction= await web3.eth.getTransaction("0X....")
console.log(JSOM.stringlify(transaction))
just not forget to define your provider and your web3 object before.

Related

Chainlink Core Adapter Path Issue: httpGet uint256 returning 0 from treasury.gov API

I am trying to connect to an API with Chainlink to get a uint from the URL in the request bellow. Problem is, every time the "volume" value comes back 0. I have a feeling the issue is one of two things:
The oracle doesn't like accessing arrays. I've tried "data[0]" as well as "data.0". Both work jsonPath which is on the Docs page.
The API is returning a string instead of a number (as the number is wrapped in quotes). I've tried a bytes32 job as well to only get back 0x0. Also other StackOverflow posts show oracles reading string numbers as numbers.
The following snippets of code are the only changes made to the "deploy on remix" code shown here in Chainlink Docs: https://docs.chain.link/docs/make-a-http-get-request.
request.add("get", "https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/avg_interest_rates?sort=-record_date");
request.add("path", "data.0.avg_interest_rate_amt");
The contracts are being deployed on Kovan through Remix/Metamask with plenty of link funding the contract. What could I be doing wrong?
There are a couple of issues:
The response is too large so the node just stops at the HttpGet task. I've tested it on my node and here's the exact error I'm getting: HTTP response too large, must be less than 32768 bytes. If you can influence this, that would be great. Otherwise, you'll need to have your own node that will return a shorter response that matches the above limitations.
The result should have only whole numbers, Solidity doesn't understand decimal points, instead, it uses WEI. That's why you need to multiply the result by at least 100, 10^18 is a standard so I'd go with that. The following piece should work for you:
function requestData(string memory _id, string memory _field) public {
Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfillData.selector);
request.add("get", "https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/avg_interest_rates?sort=-record_date");
string[] memory path = new string[](3);
path[0] = "data";
path[1] = _id;
path[2] = _field;
request.addStringArray("path", path);
int timesAmount = 10**18;
request.addInt("times", timesAmount);
sendChainlinkRequestTo(oracle, request, fee);
}
I also added _id and _field as function arguments to query any field of any object. Note, this will only work if you can figure out how to get a shorter response.

How the input data of smart contract function is packed in hex string before sending to ethereum network

I want to understand this to parse data from the private chain transaction and get the input data that was sent for a particular transaction, I have tried many decoders but at some point, they fail.
This is the simple smart contract I tried using remix
contract simple{
uint256 deliveryID;
string status;
function stringAndUint(string _status,uint256 _deliveryID){
status=_status;
deliveryID=_deliveryID;
}
}
Input data generated:- 0x3c38b7fd0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000067374617475730000000000000000000000000000000000000000000000000000
I can interpret the following from the above.
function signature:0x3c38b7fd
_status value:737461747573,
_deliveryID:0c but i dont know why 4 is coming and extra 6 before 737461747573 .
The input to function "stringAndUint " is: "status",12
Can some one help me understand how the input data is generated and packet in a long hex string
Try taking a look here http://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#argument-encoding and here http://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#use-of-dynamic-types
Splitting up the encoding into 32 byte chunks gives:
3c38b7fd (function signature)
0000000000000000000000000000000000000000000000000000000000000040 (the location of the data part of the first parameter, measured in bytes from the start of the arguments block)
000000000000000000000000000000000000000000000000000000000000000c (12)
0000000000000000000000000000000000000000000000000000000000000006 (length of "status". the earlier 0..040 points here)
7374617475730000000000000000000000000000000000000000000000000000 ("status" then zeros padded out to the next multiple of 32 bytes)
What is the encoding used?
Solidity uses a "Contract ABI" spec for encoding.
What's the deal with the extra (hex) 40 and 6?
#Brendan's answer about these values is better than mine, so I'll delete this section. I'll leave the answer posted because the below section is still useful.
Reproducing programatically
There is an ABI-decoding tool in python, called eth-abi, which you can use like so:
from eth_utils import to_bytes
encoded = to_bytes(hexstr="0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000067374617475730000000000000000000000000000000000000000000000000000")
from eth_abi import decode_abi
decoded = decode_abi(['string', 'uint256'], encoded)
assert decoded == (b'status', 12)

How to send messages on a transaction in the Ethereum

I want to send a message on a transaction. Here is my codes:
_data = web3.toHex('xxxx');
instance.function_name(param1, param2, param3, param4, {value: web3.toWei(_price, 'ether'), from: web3.eth.accounts[0], data:_data}).then(...);
The transaction is processed successfully, But the input data message is not the _data value in the etherscan.io
can anybody help me? Thank you.
The data field in the transaction object is used when deploying a contract or when using the general sendTransaction or sendRawTransaction methods. If you are using a contract instance, the data field is ignored.
From the Solidity docs:
Object - (optional) The (previous) last parameter can be a transaction object, see web3.eth.sendTransaction parameter 1 for more. Note: data and to properties will not be taken into account.
If you want to send the data manually, use sendTransaction.
The information shown in Etherscan is the decoded data from the signed transaction describing the function call made. It is not free form user data (if that's what you're trying to insert). The first 32 bits of the data are the function signature and each 256 bit block afterwards are the parameters.
See this source for more in-depth information.

What is address(0) in Solidity

Can anyone explain to me what address(0) is in Solidity? I found the following in the docs but it doesn't really make sense to me:
If the target account is the zero-account (the account with the address 0), the transaction creates a new contract. As already mentioned, the address of that contract is not the zero address but an address derived from the sender and its number of transactions sent (the “nonce”). The payload of such a contract creation transaction is taken to be EVM bytecode and executed. The output of this execution is permanently stored as the code of the contract. This means that in order to create a contract, you do not send the actual code of the contract, but in fact code that returns that code.
http://solidity.readthedocs.io/en/develop/introduction-to-smart-contracts.html?highlight=address(0)#index-8
Within an Ethereum transaction, the zero-account is just a special case used to indicate that a new contract is being deployed. It is literally '0x0' set to the to field in the raw transaction.
Every Ethereum transaction, whether it's a transfer between two external accounts, a request to execute contract code, or a request to deploy a new contract, are encoded in the same way. A raw transaction object will look something like this:
transaction = {
nonce: '0x0',
gasLimit: '0x6acfc0', // 7000000
gasPrice: '0x4a817c800', // 20000000000
to: '0x0',
value: '0x0',
data: '0xfffff'
};
If to is set to something other than '0x0', this request will result in transferring ether to the address (if value is non-zero), and execute the function encoded in the data field. Remember, the address can either be a contract or an external account.
When the to address is the zero-address, a new contract will be created by executing the code in data (this is what is meant by "code that returns the code"). The address of the newly created contract is technically known beforehand as it's based on the address of the sender and it's current nonce. That address becomes the official address of the contract after mining.
For a pretty good read on Ethereum transactions, check out this blog post.
Note: There is also the actual Solidity code statement address(0) which is the initial value of a variable of type address. The documentation you posted, however, is referring to specifically when the to account address in a transaction is set to '0x0'.
It's not actually true that a contract creation transaction has a "to" field set to the zero address (meaning 0x00...000). This is an easy mistake to make (and I've made it too) as it is described that way in many resources.
The passage you cite from the Solidity docs were updated to state this:
If the target account is not set (the transaction does not have a
recipient or the recipient is set to null), the transaction creates a
new contract. As already mentioned, the address of that contract is
not the zero address but an address derived from the sender and its
number of transactions sent (the “nonce”).
So you can see they realized at some point that the recipient field should be empty. I've actually looked at serialized creation transactions and found 0x80 there instead of an RLP-ed zero address.
In fact, 0x80 is the RLP encoding of an empty byte array, which is what the Yellow Paper states is the recipient for a contract creation:
The address hash $T_t$ is slightly different: it is either a 20-byte
address hash or, in the case of being a contract-creation transaction
(and thus formally equal to ∅), it is the RLP empty byte sequence and
thus the member of $B_0$
As I said, this is a common source of confusion. In that vein, this GitHub PR rolling back a mistakenly "fixed" test is amusing. It has the comment:
RLP encoding of 0 is encoding of empty byte array, so 0x80 is correct.
0x00 is encoding of byte array of length 1 containing one byte 0, not
encoding of integer 0.

Is currying just a way to avoid inheritance?

So my understanding of currying (based on SO questions) is that it lets you partially set parameters of a function and return a "truncated" function as a result.
If you have a big hairy function takes 10 parameters and looks like
function (location, type, gender, jumpShot%, SSN, vegetarian, salary) {
//weird stuff
}
and you want a "subset" function that will let you deal with presets for all but the jumpShot%, shouldn't you just break out a class that inherits from the original function?
I suppose what I'm looking for is a use case for this pattern. Thanks!
Currying has many uses. From simply specifying default parameters for functions you use often to returning specialized functions that serve a specific purpose.
But let me give you this example:
function log_message(log_level, message){}
log_error = curry(log_message, ERROR)
log_warning = curry(log_message, WARNING)
log_message(WARNING, 'This would be a warning')
log_warning('This would also be a warning')
In javascript I do currying on callback functions (because they cannot be passed any parameters after they are called (from the caller)
So something like:
...
var test = "something specifically set in this function";
onSuccess: this.returnCallback.curry(test).bind(this),
// This will fail (because this would pass the var and possibly change it should the function be run elsewhere
onSuccess: this.returnCallback.bind(this,test),
...
// this has 2 params, but in the ajax callback, only the 'ajaxResponse' is passed, so I have to use curry
returnCallback: function(thePassedVar, ajaxResponse){
// now in here i can have 'thePassedVar', if
}
I'm not sure if that was detailed or coherent enough... but currying basically lets you 'prefill' the parameters and return a bare function call that already has data filled (instead of requiring you to fill that info at some other point)
When programming in a functional style, you often bind arguments to generate new functions (in this example, predicates) from old. Pseudo-code:
filter(bind_second(greater_than, 5), some_list)
might be equivalent to:
filter({x : x > 5}, some_list)
where {x : x > 5} is an anonymous function definition. That is, it constructs a list of all values from some_list which are greater than 5.
In many cases, the parameters to be omitted will not be known at compile time, but rather at run time. Further, there's no limit to the number of curried delegates that may exist for a given function. The following is adapted from a real-world program.
I have a system in which I send out command packets to a remote machine and receive back response packets. Every command packet has an index number, and each reply bears the index number of the command to which it is a response. A typical command, translated into English, might be "give me 128 bytes starting at address 0x12300". A typical response might be "Successful." along with 128 bytes of data.
To handle communication, I have a routine which accepts a number of command packets, each with a delegate. As each response is received, the corresponding delegate will be run on the received data. The delegate associated with the command above would be something like "Confirm that I got a 'success' with 128 bytes of data, and if so, store them into my buffer at address 0x12300". Note that multiple packets may be outstanding at any given time; the curried address parameter is necessary for the routine to know where the incoming data should go. Even if I wanted to write a "store data to buffer" routine which didn't require an address parameter, it would have no way of knowing where the incoming data should go.