I am not talking of the data
field in the transaction.
Well, you are, actually. The data
field is the input parameters. What you need to know is how to decode them. It's well worth studying the Ethereum ABI if you really want to understand this.
For tools to help, have a look at web3.eth.abi (check you are using v1.0 or higher of Web3). Unfortunately this doesn't do the whole job for you - it could be extended to do so - but it can help.
In your example, your function call will have a signature as follows:
> web3.eth.abi.encodeFunctionSignature('setName(string)');
'0xc47f0027'
So, if you find a data
field that begins c47f0027
, you know that it is a call to your setName
function and that the remaining data is the string parameter.
In your example, the string data will look like this: 000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000054162636465000000000000000000000000000000000000000000000000000000
. This is the ABI string representation of "Abcde").
So you extract this from the data
and feed it into Web3 to decode it as follows:
> web3.eth.abi.decodeParameter('string','000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000054162636465000000000000000000000000000000000000000000000000000000');
'Abcde'
Summary
To summarise your example, the full data
field in the transaction would be "0xc47f0027000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000054162636465000000000000000000000000000000000000000000000000000000".
The first 8 hex characters, "c47f0027" (ignore the 0x if present), mean that this is a call to your setName(string n)
function.
The remaining data is your string parameter and can be decoded using Web3 as above.
Appendix
These libraries look to automate the above, but I haven't tested them:
If you observe the balance check tool, you can see there are two options
- Date
- Block Number
If you know the block number, you can use the following function to get the historic balance
web3.eth.getBalance(address, blockNumber).then(balance => `Balance at block number is ${balance}
If you dont know the block number, but want to get it by date/time. You first need to find the block that is mined during that time.
let blockNum = web3.eth.blockNumber;
const historicTimestamp = new Date(historicDate).getTime();
while(true) {
const block = web3.eth.getBlock(blockNum);
if(block.timestamp < historicTimestamp) break;
--blockNum;
}
//The blockNumber here is your required block number
web3.eth.getBalance(address, blockNumber).then(balance => `Balance at block number is ${balance}`);
Best Answer
This must be done off-chain for standard tokens.
The ERC-721 standard specification -- http://eips.ethereum.org/EIPS/eip-721 -- does not provide an interface to query historical ownership of a token. Other extensions to the standard may include this additional functionality but this will be implemented on a contract-by-contract basis. For example, CryptoKitties (as deployed) will never provide a way to get this information, regardless of what other technologies emerge.
For off-chain applications (dApps, servers) you can find this information by searching the
Transfer
event and building your own database of transfers and other log information.For casual inspection, just look up the token on Etherscan, they have a website where you can find each contract and the tokens on them.