如何通过使用 web3j 的交易获得合同?
How to get a contract by a transaction uising web3j?
我需要检查一笔交易是否是一笔ERC721/ERC1155交易,并获取接收地址、代币地址、价值等信息。如果我理解正确,我必须加载交易合约并检查如果它继承了 ERC165 以确认它是一个 ERC721/ERC1155 交易。
问题:我不明白如何获得具有交易对象的合同。我也没有找到获取令牌地址的方法。
我在 Infura 上有一个以太坊节点,我从那里读取块并迭代交易。我收到一笔交易及其收据。我的代码如下所示:
var tr = web3j.ethGetTransactionByBlockNumberAndIndex(blockIdParam, transactionIndex).sendAsync().get();
var hash = tr.getTransaction().get().getHash();
var receipt = web3.ethGetTransactionReceipt(hash).send().getTransactionReceipt();
现在我正在阅读事务日志,检查它们的主题并验证它们是否包含 Transfer
事件。但是转账事件也是由ERC20交易发出的,所以我在这里有点困惑。
检查 Transfer()
事件日志,您的方向是正确的。即使 ERC20 and ERC721 使用相同的事件签名,ERC721 (NFT) 标准将第 3 个主题(令牌 ID)定义为 indexed
,它将其值存储在索引主题集中。虽然 ERC20 将第 3 个主题(数量)定义为 non-indexed,但索引主题的总长度设置为 2.
我随机选择了一个 transaction,其中包含 ERC20 和 ERC721 传输的事件日志。看起来其背后的逻辑是以 ERC20 代币的形式支付以铸造新的 ERC721 代币。
注意:我不是 Java 开发人员,所以我将在我的回答中使用 JS 代码,希望您可以将其用作参考以找到正确的语法和方法在 Web3 库的 Java 实现中。
const Web3 = require("web3");
const web3 = new Web3("<provider_url>");
// keccak256 of string "Transfer(address,address,uint256)"
const TRANSFER_SIGNATURE = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
async function run() {
const txHash = "0xfb4dc20b4a8d0b72442a396aced0fc537de757c6aac69609ab3d09d19f9c9aa8";
const txReceipt = await web3.eth.getTransactionReceipt(txHash);
for (let log of txReceipt.logs) {
if (_isERC20Log(log)) {
// Unindexed topics are concatenated in the `data` field.
// There's only one unindexed topic in this case,
// so you don't need to do any parsing and just use the whole value.
const amount = web3.utils.hexToNumberString(log.data);
console.log("ERC20 token amount: ", amount);
console.log("ERC20 token contract: ", log.address);
} else if (_isERC721Log(log)) {
// 3rd indexed topic
// index 0 of the array is the event signature, see `_isERC721Log()`
const tokenId = web3.utils.hexToNumberString(log.topics[3]);
console.log("ERC721 token ID: ", tokenId);
console.log("ERC721 token contract: ", log.address);
}
}
}
function _isERC20Log(log) {
return (
log.topics[0] == TRANSFER_SIGNATURE
&& log.topics.length == 3 // index 0 is the signature, and then 2 indexed topics
);
}
function _isERC721Log(log) {
return (
log.topics[0] == TRANSFER_SIGNATURE
&& log.topics.length == 4 // index 0 is the signature, and then 3 indexed topics
);
}
run();
输出:
ERC20 token amount: 40000000000000000000
ERC20 token contract: 0x54a7cee7B02976ACE1bdd4aFad87273251Ed34Cf
ERC721 token ID: 12013
ERC721 token contract: 0x41cB4a771FdD019ADBF4685bd4885fbBeedE1784
我需要检查一笔交易是否是一笔ERC721/ERC1155交易,并获取接收地址、代币地址、价值等信息。如果我理解正确,我必须加载交易合约并检查如果它继承了 ERC165 以确认它是一个 ERC721/ERC1155 交易。
问题:我不明白如何获得具有交易对象的合同。我也没有找到获取令牌地址的方法。
我在 Infura 上有一个以太坊节点,我从那里读取块并迭代交易。我收到一笔交易及其收据。我的代码如下所示:
var tr = web3j.ethGetTransactionByBlockNumberAndIndex(blockIdParam, transactionIndex).sendAsync().get();
var hash = tr.getTransaction().get().getHash();
var receipt = web3.ethGetTransactionReceipt(hash).send().getTransactionReceipt();
现在我正在阅读事务日志,检查它们的主题并验证它们是否包含 Transfer
事件。但是转账事件也是由ERC20交易发出的,所以我在这里有点困惑。
检查 Transfer()
事件日志,您的方向是正确的。即使 ERC20 and ERC721 使用相同的事件签名,ERC721 (NFT) 标准将第 3 个主题(令牌 ID)定义为 indexed
,它将其值存储在索引主题集中。虽然 ERC20 将第 3 个主题(数量)定义为 non-indexed,但索引主题的总长度设置为 2.
我随机选择了一个 transaction,其中包含 ERC20 和 ERC721 传输的事件日志。看起来其背后的逻辑是以 ERC20 代币的形式支付以铸造新的 ERC721 代币。
注意:我不是 Java 开发人员,所以我将在我的回答中使用 JS 代码,希望您可以将其用作参考以找到正确的语法和方法在 Web3 库的 Java 实现中。
const Web3 = require("web3");
const web3 = new Web3("<provider_url>");
// keccak256 of string "Transfer(address,address,uint256)"
const TRANSFER_SIGNATURE = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
async function run() {
const txHash = "0xfb4dc20b4a8d0b72442a396aced0fc537de757c6aac69609ab3d09d19f9c9aa8";
const txReceipt = await web3.eth.getTransactionReceipt(txHash);
for (let log of txReceipt.logs) {
if (_isERC20Log(log)) {
// Unindexed topics are concatenated in the `data` field.
// There's only one unindexed topic in this case,
// so you don't need to do any parsing and just use the whole value.
const amount = web3.utils.hexToNumberString(log.data);
console.log("ERC20 token amount: ", amount);
console.log("ERC20 token contract: ", log.address);
} else if (_isERC721Log(log)) {
// 3rd indexed topic
// index 0 of the array is the event signature, see `_isERC721Log()`
const tokenId = web3.utils.hexToNumberString(log.topics[3]);
console.log("ERC721 token ID: ", tokenId);
console.log("ERC721 token contract: ", log.address);
}
}
}
function _isERC20Log(log) {
return (
log.topics[0] == TRANSFER_SIGNATURE
&& log.topics.length == 3 // index 0 is the signature, and then 2 indexed topics
);
}
function _isERC721Log(log) {
return (
log.topics[0] == TRANSFER_SIGNATURE
&& log.topics.length == 4 // index 0 is the signature, and then 3 indexed topics
);
}
run();
输出:
ERC20 token amount: 40000000000000000000
ERC20 token contract: 0x54a7cee7B02976ACE1bdd4aFad87273251Ed34Cf
ERC721 token ID: 12013
ERC721 token contract: 0x41cB4a771FdD019ADBF4685bd4885fbBeedE1784