使用 Metamask 进行 RPC 调用
RPC call with Metamask
我想使用 metamask 从我的应用创建一个 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.log(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
被编码为 dynamic-length 字节数组,包括指向数组开始位置的第一个 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.log(data);
打印
# formatted for readability
0x10a7b27a
0000000000000000000000000000000000000000000000000000000000000020
0000000000000000000000000000000000000000000000000000000000000003
666f6f0000000000000000000000000000000000000000000000000000000000
- 第一个槽是指向数组开始位置的指针。在这种情况下 (hex20 == dec32) 这是第二个插槽的开始。
- 第二个插槽(值 3)是值的长度
- 第三个插槽包含字符串的实际 hex-encoded 值
解决方案:这个长值(没有换行符)是你需要传递的。
我想使用 metamask 从我的应用创建一个 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.log(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
被编码为 dynamic-length 字节数组,包括指向数组开始位置的第一个 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.log(data);
打印
# formatted for readability
0x10a7b27a
0000000000000000000000000000000000000000000000000000000000000020
0000000000000000000000000000000000000000000000000000000000000003
666f6f0000000000000000000000000000000000000000000000000000000000
- 第一个槽是指向数组开始位置的指针。在这种情况下 (hex20 == dec32) 这是第二个插槽的开始。
- 第二个插槽(值 3)是值的长度
- 第三个插槽包含字符串的实际 hex-encoded 值
解决方案:这个长值(没有换行符)是你需要传递的。