Я отправляю транзакцию на счет с некоторыми данными с помощью следующей команды:
eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:web3.toWei(1,"ether"),data:web3.toHex("http://localhost:8545")})
Я получаю этот результат, извлекая журнал транзакции (работая с testRPC):
tx hash : 0xf654aee5ed23f9aeebd2d73c69c7b9c21a4862787966d09bcb09ed44efc1f252
nonce : 0
blockHash : 0x6ff8a0e3ac606abd2ede4331b82af52a0daa98448025051fb3b3d50f749aa49f
blockNumber : 1
transactionIndex: 0
from : 0xf64918835bc21dff9e8210a807b3964d1be35dd0
to : 0x08f986b7535c2b72687d3cb193135f1c6e27c336
value : 1000000000000000000
time : 1483614904 Thu, 05 Jan 2017 11:15:04 GMT
gasPrice : 1
gas : 90000
input : 0x687474703a2f2f6c6f63616c686f73743a38353435
Я хочу декодировать последнюю строку «ввод» и попытаться получить « http://localhost:8545 ». Я видел некоторые работы, похожие на мой вопрос здесь и здесь , но это не работает в моем случае. Более того, я пытался, .toString('hex'))
но он остается шестнадцатеричным.
Как я могу этого добиться?
заранее спасибо
Вы можете сделать, web3.toAscii(transactionID.input)
чтобы вернуть данные в читаемом формате.
Читать web3.toAscii
Для декодирования данных вы можете использовать библиотеку под названием abi-decoder .
Вам нужно будет предоставить ABI для смарт-контракта, который вы хотите декодировать, а затем просто вставьте входные данные. Очень простой.
Единственное падение произойдет, если ваши входные данные окажутся созданием смарт-контракта «Конструктор», тогда в этом случае вам придется изменить библиотеку, чтобы приспособиться к этому.
Если вы слышали о библиотеке ethers js , она предоставляет фантастическую функцию с именем parseTransaction. Я нашел ее после очень долгих поисков, так как она не упоминалась ни на одном онлайн-форуме, и я все еще многому учусь.
Но я обнаружил, что это лучше всего подходит для декодирования любого вида контракта и связанного с ним вызова функции.
const ethers = require('ethers');
const ABI = require('./abi.json'); // Contract ABI
const provider = ethers.getDefaultProvider();
const inter = new ethers.utils.Interface(ABI);
(async() => {
const tx = await provider.getTransaction('0xa30e9e19967bd3307feeddcf99b26be0d804cdc0ade6929f3b9328a95e388b4c');
const decodedInput = inter.parseTransaction({ data: tx.data, value: tx.value});
// Decoded Transaction
console.log({
function_name: decodedInput.name,
from: tx.from,
to: decodedInput.args[0],
erc20Value: Number(decodedInput.args[1])
});
})();
Обратите внимание, что для этого вам понадобится ABI контракта.
Используйте @ethersproject/abi
, это самый безопасный подход из всех. Эфиры протестированы в тысячах проектов Ethereum, и, скорее всего, в его реализации кодирования/декодирования ABI нет ошибок.
Мы сделали хороший инструмент для декодирования. Просто вставьте хэш транзакции в поле ввода и получите результат. Проверьте это . Он работает с Mainnet, Kovan, Ropsten и Rinkeby, но код контракта должен быть проверен в Etherscan. Мы используем API Etherscan для получения данных о транзакциях и контрактах, а также web3 для декодирования.
Эта библиотека JavaScript/Node.js может декодировать входные данные смарт-контракта и входные данные создания контракта с учетом JSON abi:
Полное определение того, что вы пытаетесь декодировать (поле входных данных), находится здесь: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI . Это непросто, но мне удалось написать код на C++, который полностью анализирует аргументы функций, записанные в транзакциях. Для вашего конкретного вопроса декодирование шестнадцатеричного кода является правильным, но для более общего случая входных данных, представляющих вызов функции и ее параметры, вам необходимо декодировать интерфейс, описанный в этом документе.
В python это делается с помощью метода контракта decode_function_input:
contract.decode_function_input(transaction.input)
видеть:
Рассмотрите возможность использования truffle и abi-decoder :
# compile contracts to generate ABIs
truffle compile
# let's do it from truffle console
truffle console
const abiDecoder = require('abi-decoder');
# take ABIs of required contracts
const { abi: abi1 } = require('./build/contracts/sc1.json');
const { abi: abi2 } = require('./build/contracts/sc2.json');
..
# register ABIs
abiDecoder.addABI(abi1);
abiDecoder.addABI(abi2);
..
# take 'TX data' of transaction & decode it (take for example the first transaction in 100th block)
let input = (await web3.eth.getTransactionFromBlock(100, 0)).input
abiDecoder.decodeMethod(input);
/* result
{
name: 'request',
params: [
{ name: '_control', value: 'control', type: 'string' },
{ name: '_tId', value: 'tid', type: 'string' },
{ name: '_number', value: 'inumber', type: 'string' }
]
}
*/
Я использую"web3": "^1.6.1",
const data = await web3.eth.getTransaction(txHash);
return web3.eth.abi.decodeParameters(
// ERC20 transfer method args
[
{ internalType: 'address', name: 'recipient', type: 'address' },
{ internalType: 'uint256', name: 'amount', type: 'uint256' },
],
`0x${txData.input.substring(10)}`
);
Первые 4 байта ввода — это сигнатура метода.
выход:
{
"0": "0x45d8253c7980d5718C5Fa3626d446886Fd857CfE",
"1": "160750000000000000000",
"__length__": 2,
"recipient": "0x45d8253c7980d5718C5Fa3626d446886Fd857CfE",
"amount": "160750000000000000000"
}
Документы: https://web3js.readthedocs.io/en/v1.2.11/web3-eth-abi.html#decodeparameters
Использование нежно является хорошим вариантом. Если вы добавите подтвержденный контракт (или у вас есть abi/источники, которые нужно добавить напрямую), вы можете предоставить необработанные данные транзакции и запустить с ними симуляцию, и она покажет вам, как декодируются входные данные.
СвапнилКумбхар
contract.addBalance.sendTransaction(contractAddress, {from: senderAddress, to: contractAddress, gas:1000000, value: web3.toWei(7, "ether"),data:web3.toHex("http://localhost:8545")})
, если я пытаюсь получить web3.toAscii(transaction.input), он возвращает некоторые случайные символические значения.никсмак
осалли
hexToAscii()
, попробуйте использоватьweb3.hexToString()
! Работал для меня, когда ниtoAscii
то , ни другое неtoUtf8
вели себя должным образом.адамк
web3.toAscii is not a function
. Чтобы решить эту проблему, используйтеweb3.utils.toAscii()
вместо этого