首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >web3.eth.call。如何设置“数据”参数?

web3.eth.call。如何设置“数据”参数?
EN

Ethereum用户
提问于 2017-07-17 05:42:19
回答 2查看 16.5K关注 0票数 8

我部署了我的第一个契约,使用浏览器的坚固性来制作字节码,使用web3.eth.sendRawTransaction进行部署。下面是事务和已部署的合同代码。

https://ropsten.etherscan.io/tx/0x74426948905cd6e70e8b9d64a660b3c179b7c8a224ca5cd0234842768eb501db

合同代码

代码语言:javascript
复制
pragma solidity ^0.4.0;
contract Addition {
  int num = 0;
  function add(int a){
    num += a;
  }
  function get() returns(int){
    return num;
  }
}

然后,我想通过web3.eth.call调用这两种方法。但是,我无法找到如何生成“数据”参数的方法。你能给我一些建议吗?

代码语言:javascript
复制
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://xxx:xxx"));

const result = web3.eth.call({
    to: "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a", 
    data: "???"
});

https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethcall

我认为气体是必要的,但这个例子并没有提到它。在浏览器可靠的JavaScript VM上,当我执行如下方法时,价格会显示出来。

代码语言:javascript
复制
Result: "0x"
Transaction cost: 41713 gas. 
Execution cost: 20249 gas.

更新1

似乎这一页描述了它。

然后,我想用数字"5“来调用这个方法"double”。合同ABI文档指出,您必须接受Keccak哈希的前4个字节。方法签名是double(int),它给出带有web3.sha3的散列(“double(Int)”:6740d36c7d42fba12b8eb3b047193c9761224c267d7a2e96dc50949860652317前四个字节,前缀为"0x“)是: 0x6740d36c文档然后告诉接受参数,将其编码为十六进制,并将其左移到32个字节。使用数字"5":0x0000000000000000000000000000000000000000000000000000000000000005总计,编码的字符串应该如下所示: 0x6740d36c0000000000000000000000000000000000000000000000000000000000000005

如何使用eth调用合同方法_调用JSON-RPC

更新2

它不起作用。

代码语言:javascript
复制
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://xxx:xxx"));

var result = web3.eth.call({
    to: "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a",
    data: "0x6d4ce63c" // var hash = web3.sha3("get()"); get first 4 byte
});

console.log(result); // 0x

var result = web3.eth.call({
    to: "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a",
    data: "0x250fc6d90000000000000000000000000000000000000000000000000000000000000001" // var hash = web3.sha3("add(int)"); get first 4 byte and param (1)
});

console.log(result); // 0x

var result = web3.eth.call({
    to: "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a",
    data: "0x6d4ce63c" // var hash = web3.sha3("get()"); get first 4 byte
});

console.log(result); // 0x => I expected 1

更新数据3

我从add(int)改为add(int256),但仍然无法工作。

代码语言:javascript
复制
var result = web3.eth.call({
    to: "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a",
    data: "0x87db03b70000000000000000000000000000000000000000000000000000000000000001" // var hash = web3.sha3("add(int256)"); get first 4 byte and param (1)
});

然而,浏览器-稳固调试器显示相同的数据。所以我认为这个数据是正确的。

更新4

看来我得在打电话之前先发交易。我可以想象。我会试试的。

打电话。这是一个只读操作,不会消耗任何以太。

交易和呼叫之间有什么区别?

更新5

虽然我觉得找到了答案,但还是不管用。我休息一下..。

(1) sendRawTransaction

代码语言:javascript
复制
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://xxxx:xxxx"));

const Tx = require('ethereumjs-tx');
const privateKey = new Buffer('xxxx', 'hex')

const rawTx = {
  nonce: '0x03',
  gasPrice: '0x53d9',
  gasLimit: '0x53d9',
  to: '0x692a70d2e424a56d2c6c27aa97d1a86395877b3a',
  data: '0x87db03b70000000000000000000000000000000000000000000000000000000000000001' // add(int256) with param 1
}

const tx = new Tx(rawTx);
tx.sign(privateKey);

const serializedTx = tx.serialize();

console.log('0x' + serializedTx.toString('hex')); // 0xf885038253d98253d994692a70d2e424a56d2c6c27aa97d1a86395877b3a80a487db03b700000000000000000000000000000000000000000000000000000000000000011ba0ec6de7c9c1f31dc95014156479925b2ebd933b715f2bb4450f5d74992d7b3423a016f6a7c6e1885412400a622f82ffa033936c06755896096c7638936c065571c1

web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), function(err, hash) {
  if (!err) {
    console.log(hash); // 0x26db79c7c3c65992f17f4f62d5d191705933e785dff54db6d27e6f3a92d7117e
  } else {
    console.log(err);
  }
});

https://ropsten.etherscan.io/tx/0x26db79c7c3c65992f17f4f62d5d191705933e785dff54db6d27e6f3a92d7117e

(2)调用get()

代码语言:javascript
复制
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://xxxx:xxxx"));

const result = web3.eth.call({
    to: "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a",
    data: "0x6d4ce63c"
});

console.log(result); // 0x => I expected 1
EN

回答 2

Ethereum用户

回答已采纳

发布于 2017-07-17 06:43:47

你不需要一个人做这些。您可以使用getData方法。

代码语言:javascript
复制
const contract = new web3.eth.Contract(contractABI, contractAddress);
const callData = contract.functionName.getData(functionParameters);
const result = web3.eth.call({
    to: "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a", 
    data: callData
});

web3.eth.call在节点的VM中执行调用,但没有挖掘该调用。这是一种尝试。如果您想要发送一个事务到块链,请使用web3.eth.sendTransaction

票数 11
EN

Ethereum用户

发布于 2017-08-29 19:14:31

就连我也不得不经历同样的过程,直到我发现,下面是:

使用web3.js库,它可以帮助完成同样的工作。只需使用NPM (或其他任何地方)下载web3.js,并通过以下方式获取任务所需的模块:

代码语言:javascript
复制
const_ = require('lodash');
const SolidityFunction = require('web3/lib/web3/function');

您可以使用web3.js库和ABI找到函数定义,使用以下代码:

代码语言:javascript
复制
var ABI = JSON.parse(<your_ABI>);
var functionDef = new SolidityFunction('', _.find(ABI, { name: '<your_function_name>' }), '');

之后,您可以调用方法toPayload,它将帮助您将要传递给函数的值转换为HEX数据。

代码语言:javascript
复制
var payloadData = functionDef.toPayload([<value_for_var_1>, <value_for_var_2>, <value_for_var_3>, <value_for_var_4>]).data;

payloadData可用作数据属性的值。示例:

代码语言:javascript
复制
var rawTx = {
 to: <to_address>,
 data: payloadData,
 value: '0x0',
 from: <from_address>,
 nonce: nonce,// You need to Get this using web3.eth.getTransactionCount
 gasLimit: gasLimit, // Get this by web3.eth.estimateGas
 gasPrice: gasPrice // use, web3.eth.gasPrice
}

您可以使用这种方法,而不需要使用多少个零。当toPayload函数处理所有事情时。您有一个原始事务对象,您可以使用以太-tx对事务进行签名,并使用web3.eth.sendRawTransaction调用您的契约函数。

希望这能有所帮助。

票数 3
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/21402

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档