admin管理员组文章数量:1278792
I would like to be able to find out the total volume transacted for RDOC, from deployment until now.
Unable to get this information from the block explorer:
0x2d919f19d4892381d58edebeca66d5642cef1a1f
What's the best way to get this using RPC or web3.js?
I would like to be able to find out the total volume transacted for RDOC, from deployment until now.
Unable to get this information from the block explorer:
0x2d919f19d4892381d58edebeca66d5642cef1a1f
What's the best way to get this using RPC or web3.js?
Share Improve this question edited Jul 13, 2021 at 5:29 bguiz 28.5k49 gold badges163 silver badges251 bronze badges asked Jun 16, 2021 at 7:24 7alip7alip 9057 silver badges11 bronze badges 1-
1
using a
web3.eth.Contract
instance and calling.getPastEvents('Transfer')
, then aggregating them should give you the answer – bguiz Commented Jun 16, 2021 at 7:45
2 Answers
Reset to default 8You can get past logs
from the block when the contract was deployed
until the current block
emitted by the token contract address
where the
topics[0]
is keccak256 of the event signatureIn case of
Transfer(address,address,uint256)
event, the keccak256 hash is0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
Since the first two params of the event are indexed, they are present in the topics[1]
(sender) and topics[2]
(receiver) fields of each event log. The third param (amount) is unindexed, so its value is in the data
field (as a hex number) of each event log.
The total transacted volume is simply a sum of all transferred amounts (from the data
field).
Mind that most RPC providers allow accessing only limited amount of historic blocks (e.g. max 100 blocks). So you might have to use a different provider or your own full node in order to access a deeper history (e.g. 200 blocks).
tl;dr= (1) init a web3.eth.Contract
instance for the RDOC deployed address;
then (2) call .getPastEvents('Transfer')
,
then (3) aggregate the sum of Transfer.value
values.
Detailed answer:
(1) Init the contract instance
There is a RPC data provider, GetBlock which you may think of as similar to an Infura that supports RSK.
For querying large amounts of data, such as historical data, Websockets can be faster/ more efficient than HTTP, so let's use their Websockets RPC endpoint for RSK Mainnet:
wss://rsk.getblock.io/mainnet/websocket
// init web3 instance
const GETBLOCK_API_KEY = /* copy the API key from GetBlock dashboard */;
const rpcWebsocketsUrl =
`wss://rsk.getblock.io/mainnet/websocket`;
const rpcWebsocketsOptions = {
timeout: 5000, // ms
headers: {
'x-api-key': GETBLOCK_API_KEY,
},
};
const web3Provider = new Web3.providers.WebsocketProvider(
rpcWebsocketsUrl,
rpcWebsocketsOptions,
);
const web3 = new Web3(web3Provider);
Once we have a web3 instance ready, we need an ABI and the token smart contract's deployed address:
// init token contract instance
const tokenAbi = require('./abi.json'); // any standard ERC20 ABI will suffice for this purpose
const tokenAddress = '0x2d919f19d4892381d58edebeca66d5642cef1a1f'; // RDOC deployed address
const token = new web3.eth.Contract(tokenAbi, tokenAddress);
(2) Get past Transfer
events
According to the ERC20 specification,
each time an amount of the token is transferred between one account
and another account, the ERC20 smart contract should emit a Transfer
event.
This event contains 3 parameters:
- The sender address,
- the receiver address,
- and the amount.
(We only care about the amount for our objective here)
In web3.js, to get past events, you should specify the range of block numbers,
and then query the past events using .getPastEvents()
.
Assuming we want to calculate the total transaction volume
of RDOC in the past week, we can use the total number of seconds in a week
divided by the number of seconds per block.
7 * (24 * 60 * 60) / 30 = 20160
Note that as with other blockchains, the time per block is approximate, therefore this gives us the number of blocks in approximately 1 week. The exact number of blocks can also be calculated by inspecting block timestamps
// get the range of blocks to query
const rangeNumberOfBlocks = 20160;
const latestBlockNumber = await web3.eth.getBlockNumber().toNumber();
const blockRange = {
fromBlock: latestBlockNumber - rangeNumberOfBlocks,
toBlock: latestBlockNumber,
};
Now we can query past events:
// get past `Transfer` events
const events = await token.getPastEvents(
'Transfer',
blockRange,
);
(3) calculate the aggregate
Each event in the events
array contains the three event parameters,
as per the ERC20 specification, however, we are only interested in event.returnValues.value
.
Note that this is returned as a BN
(BigNumber),
and for good reason - it is a uint256
, which is too large for Javascript's built in Number
type.
Also note that this number has a certain number of decimal places that it should be divided by, also specified in the ERC20 specification.
// prepare for division for decimal places
const decimals = await token.methods.decimals().call();
const decimalsExp = new web3.utils.BN(10).pow(new web3.utils.BN(decimals));
For most tokens, including RDOC, we expect decimalsExp
to be 1e18 (1000000000000000000).
Finally, we can loop over the events
, and calculate the aggregate value.
Below I'm using
.iadd()
instead of.add()
so that the addition can occur in-place, so as to avoid reassignment/ memory allocation overhead (but this is optional).
const sum = new web3.utils.BN(0);
for (let eventIdx = 0; eventIdx < events.length; eventIdx += 1) {
const event = events[eventIdx];
sum.iadd(
new web3.utils.BN(event.returnValues.value),
);
}
const displaySum = sum.div(decimalsExp).toString();
displaySum
should be the total amount of transacted RDOC for the selected time period.
本文标签: javascriptHow to calculate the total volume transacted for a token on RSKStack Overflow
版权声明:本文标题:javascript - How to calculate the total volume transacted for a token on RSK? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741262253a2367844.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论