Я хочу создать вызов RPC (цель исследования) из своего приложения, используя метамаску.
Мой метод по моему контракту:
function sayHelloMyName(string memory _name) external pure returns (string memory) {
require(bytes(_name).length != 0, "insert your name");
return string(abi.encodePacked("hello ", _name));
}
его хэш:
$ web3.utils.keccak256("sayHelloMyName(string)").substr(0, 10)
> '0x10a7b27a'
Я хочу передать свое имя foo, где шестнадцатеричное десятичное число равно 0x666f6f.
web3.utils.toHex('foo')
'0x666f6f'
Итак, мой призыв:
ethereum
.request({
method: 'eth_call',
params: [
{
from: currentAccount,
to: contractAddress,
data: 0x10a7b27a0000000000000000000000000000000000000000000000000000000000666f6f
}, "latest"],
})
.then((txHash) => {
console.info(txHash);
$('#info').html(txHash);
})
.catch((error) => {
console.error;
$('#info').text(JSON.stringify(error.message));
});
где данные — это сигнатура метода, мое шестнадцатеричное имя и заполнение (всего 32 байта) К сожалению, я получаю возврат этого.
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32000,
"message": "execution reverted"
}
}
код работает, я могу использовать его с библиотекой web3.
Solidity string
кодируется как массив байтов динамической длины, включая первый 32-байтовый слот, указывающий на расположение начала массива, и второй 32-байтовый слот, содержащий длину строки. Значение: Не только шестнадцатеричное значение строки, которую вы передаете.
Это работает с web3js
, потому что библиотека JS декодирует возвращает шестнадцатеричный код к строке (web3 предполагает, что ввод шестнадцатеричный, так как он начинается с 0x
), а затем кодирует правильно к массиву байтов при заполнении поля data
.
Смотрите вывод этого web3js
фрагмента
const data = web3.eth.abi.encodeFunctionCall({
name: 'sayHelloMyName',
type: 'function',
inputs: [{
type: 'string',
name: '_name'
}]
}, [
'foo',
]);
console.info(data);
который печатает
# formatted for readability
0x10a7b27a
0000000000000000000000000000000000000000000000000000000000000020
0000000000000000000000000000000000000000000000000000000000000003
666f6f0000000000000000000000000000000000000000000000000000000000
Решение: Это длинное значение (без новой строки) — это то, что вам нужно вместо этого передать.
Итак, если я хочу использовать eth_sendTransaction
с метамаской со значением и данными, я должен создать данные с подписью метода (4 байта) + параметры, которые я могу создать с помощью encodeParam, как вы сказали, значение в шестнадцатеричном формате. Потому что с web3.eth.sendTransaction
мне нужен закрытый ключ пользователя, поэтому я предполагаю, что sendTransaction предназначен для «серверной стороны». Спасибо за ваше время.
честно говоря, у меня есть сомнения по поводу hex20, первого слота, где я могу найти больше информации о нем?
@foo_bar См. offset
о первом слоте: docs.soliditylang.org/en/v0.8.13/…
Удивительно, это ответ, который я ищу!