使用 web3.js 从交易中获取 USDC(或任何非 ETH 值)
Posted
技术标签:
【中文标题】使用 web3.js 从交易中获取 USDC(或任何非 ETH 值)【英文标题】:Get USDC (or any non-ETH value) from transaction using web3.js 【发布时间】:2022-01-07 15:52:45 【问题描述】:我正在一个小项目上使用 web3.js 库,该项目订阅智能合约上的事件,以便 NFT 通过 OpenSea 跟踪该项目的所有销售。这在使用 ETH 完成销售时工作正常,但是当使用 OpenSea 提供的另一种支付方式(USDC、DAI、WETH 等)进行销售时,来自 web3.js 的交易价值返回为 0 ,它在 etherscan.io 上也显示 0。以下是代表此问题的示例事务:https://etherscan.io/tx/0x17f050e3fb6d8f0bbb4d9b4e8cd477f8197a87a3a68b360a60a028d7b1037532。无论使用什么类型的货币,关于如何获得正确价值的任何想法?
前web3.eth.getTransaction('0x17f050e3fb6d8f0bbb4d9b4e8cd477f8197a87a3a68b360a60a028d7b1037532').then((response) => console.log(response); );
回应
accessList: [],
blockHash: '0x6140d3cb5c271fb351e0a6e9e35b32cf0607ad526152f40f2d98107a97b0212b',
blockNumber: 13545512,
chainId: '0x1',
from: '0x3F4D7b0Eba8CB40D94713023d9Dc02FdB0a5169C',
gas: 391246,
gasPrice: '157998874325',
hash: '0x17f050e3fb6d8f0bbb4d9b4e8cd477f8197a87a3a68b360a60a028d7b1037532',
input: '0xab834bab0000000000000000000000007be8076f4ea4a4ad08075c2508e481d6c946d12b00000000000000000000000074144fb8749f99382091118f7487f4a541be6d7700000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b3256965e7c3cf26e11fcaf296dfc8807c01073000000000000000000000000bd3531da5cf5857e7cfaa92426877b022e612cf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007be8076f4ea4a4ad08075c2508e481d6c946d12b0000000000000000000000003f4d7b0eba8cb40d94713023d9dc02fdb0a5169c00000000000000000000000074144fb8749f99382091118f7487f4a541be6d770000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd3531da5cf5857e7cfaa92426877b022e612cf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000226000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000165a0bc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000618193b7000000000000000000000000000000000000000000000000000000006182e53b690c3f82a9b6570ef2de1af15e15942c931dba8a2bd9d5012b74b213beea4da400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000226000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000165a0bc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006182d5b70000000000000000000000000000000000000000000000000000000000000000065ae400a094fafb63173dcf4c7861ca0264920136639dbe27b5956aa6282bb00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a0000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000007e0000000000000000000000000000000000000000000000000000000000000088000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001c08da96edfaed45809c68db44cabb487dba56fd196fe46d02d679f0161dee94293eaedf214e043bc4d2e3dd69cce82e21ead967d7f1cd8fc505c04781e2d144e308da96edfaed45809c68db44cabb487dba56fd196fe46d02d679f0161dee94293eaedf214e043bc4d2e3dd69cce82e21ead967d7f1cd8fc505c04781e2d144e35c5321ae45550685308a405827575e3d6b4a84aa000000000000000000000000000000000000000000000000000000000000000000000000000000000000006423b872dd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074144fb8749f99382091118f7487f4a541be6d7700000000000000000000000000000000000000000000000000000000000008ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006423b872dd0000000000000000000000003f4d7b0eba8cb40d94713023d9dc02fdb0a5169c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006400000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
maxFeePerGas: '201893464202',
maxPriorityFeePerGas: '1500000000',
nonce: 19,
r: '0x4c8e6fbe4a49439d957e0e725f3f7e897329557a972863143ff2a34458ab190',
s: '0x25afd4caa4cdc1f93923b5f41a89bc191d0e52c27a36e51e3015ed08560fea5d',
to: '0x7Be8076f4EA4A4AD08075C2508e481d6C946D12b',
transactionIndex: 328,
type: 2,
v: '0x1',
value: '0'
【问题讨论】:
【参考方案1】:您可以获得包含事件日志的交易收据。在这种情况下,您正在寻找 ERC-20 合约发出的 Transfer
事件,其中 ERC-20 代币发送者与 NFT 接收者相同。
const run = async () =>
const receipt = await web3.eth.getTransactionReceipt('0x17f050e3fb6d8f0bbb4d9b4e8cd477f8197a87a3a68b360a60a028d7b1037532');
const nftReceiver = _getNFTReceiver(receipt.logs);
for (let log of receipt.logs)
// keccak256 of "Transfer(address,address,uint256)"
if (log.topics[0] === '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
// ERC20 sender (1st param of the Transfer event) is the same as the NFT receiver
&& web3.eth.abi.decodeParameter('address', log.topics[1]).toLowerCase() === nftReceiver.toLowerCase()
// ERC-20 Transfer returns the value in `data`, while ERC-721 has the same signature but returns empty data
&& log.data !== '0x'
)
console.log('ERC-20 token contract: ', log.address);
console.log('ERC-20 token amount (incl. decimals): ', web3.eth.abi.decodeParameter('uint256', log.data));
const _getNFTReceiver = (logs) =>
for (let log of logs)
// keccak256 of "Transfer(address,address,uint256)"
if (log.topics[0] === '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
// ERC-20 Transfer returns the value in `data`, while ERC-721 has the same signature but returns empty data
&& log.data === '0x'
)
// 2nd parameter of the `Transfer()` event contains the NFT receiver
return web3.eth.abi.decodeParameter('address', log.topics[2]);
return null;
run();
打印:
Token contract: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Token amount (incl. decimals): 6000000000
【讨论】:
您是救生员,先生。_getNFTReceiver ()
中的硬编码地址代表什么?所有智能合约的价值都相同吗?非常感谢您的帮助!
@TylerPashigian 它是字符串 Transfer(address,address,uint256)
的 keccak-256 哈希值。该字符串表示 ERC-20 和 ERC-721 代币合约在传输代币时都应该发出的事件。对于遵循这些标准的所有代币合约,其价值是相同的。
我明白了,谢谢你的解释!最后一个问题,当将令牌金额转换为正确的十进制值时,您需要获取该令牌的小数位数,我假设如果不向 api(例如 etherscan)发出单独的请求,就无法获取令牌信息获取代币符号、使用价值、小数点等?
@TylerPashigian 如果代币合约遵循 ERC20 标准,它还应该实现返回小数位数的decimals()
函数,以及name()
和symbol()
函数以获得额外的有关令牌的信息。因此,您可以直接调用令牌合约来检索值。另一个有效的解决方案是查询 3rd 方 API(例如 Etherscan),正如您的评论所说,它通常还包括当前市场价格(不是由代币合约单独提供)和其他附加信息。
@TylerPashigian 没有 ABI,这很复杂。如果您假设合约实现了一个标准,您可以使用该标准的通用 ABI(例如 ERC-20;在 Google 上搜索“ERC-20 ABI”)。它无法访问在标准上扩展的特定合约的功能,但至少它是……否则,您可以使用反编译器从(编译的)字节码生成伪代码并从中手动构建 ABI .请参阅 Etherscan/BSCScan 地址详细信息页面上的“反编译”选项...但通常,如果没有 ABI,很难与合约进行通信。以上是关于使用 web3.js 从交易中获取 USDC(或任何非 ETH 值)的主要内容,如果未能解决你的问题,请参考以下文章
如何获取在与@solana/web3.js 的交易中转移的自定义令牌数量?
以太坊如何使用web3.js或者rpc接口获取交易数据交易时间与确认数?