Web3js调用和truffle调用的行为不同



我有一份合同,看起来像这样-

contract Calculator {
uint public result;
constructor() public {
result = 777;   //note the initial value
}
function add(uint a, uint b) public returns (uint, address) {
result = a + b;
return (result, msg.sender);
}
}

当我调用松露上的函数时,我会得到一个正确的事务-

truffle(development)> await calculator.add(5,11)
{
tx: '0xa66e94bb28810bb2a861c97ee149718afa599d47b7b1c6e55743ea657fdeef56',
receipt: {
transactionHash: '0xa66e94bb28810bb2a861c97ee149718afa599d47b7b1c6e55743ea657fdeef56',
transactionIndex: 0,
blockHash: '0x6ae4e3ce65f1e177c419306a50662ed46f40c729a6a18ede028b07e63dd12f61',
blockNumber: 6,
from: '0x5d88950b52f89ad66906fc263e8c35ddacff04d4',
to: '0x7c8beb382c70cbf12b41fd4e5d74cfee53fdc391',
gasUsed: 26074,
cumulativeGasUsed: 26074,
contractAddress: null,
logs: [ [Object] ],
status: true,
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000200000000000000000000000000000000000000',
rawLogs: [ [Object] ]
},
logs: [
{
logIndex: 0,
transactionIndex: 0,
transactionHash: '0xa66e94bb28810bb2a861c97ee149718afa599d47b7b1c6e55743ea657fdeef56',
blockHash: '0x6ae4e3ce65f1e177c419306a50662ed46f40c729a6a18ede028b07e63dd12f61',
blockNumber: 6,
address: '0x7C8beb382C70CbF12b41fd4e5d74CfEe53FDc391',
type: 'mined',
id: 'log_28a5e84f',
event: 'Added',
args: [Result]
}
]
}

我正在使用Web3js调用相同的函数,比如

const Web3 = require("web3");
const CalculatorContract = require("../build/contracts/Calculator.json");
let web3 = new Web3(new Web3.providers.WebsocketProvider("ws://127.0.0.1:7545"));
async sendTransaction () {
let accounts = await web3.eth.getAccounts();
let contractAddress = "0x7C8beb382C70CbF12b41fd4e5d74CfEe53FDc391";
let calculatorContract = new web3.eth.Contract(CalculatorContract.abi, contractAddress);
console.log("Calculator adding: ", await calculatorContract.methods.add(11, 88).call({
from: '0x38e3614A5Cf95f0DBb858D9E3752Ac477DA70ccD'
}));
console.log("Calculator result: ", await calculatorContract.methods.result().call());
}

当我调用上面的函数时,我得到的输出是这样的-

Calculator adding:  Result {0: '99', 1: '0x5d88950b52F89AD66906fC263E8C35DdacFf04D4'}
Calculator result:  777     //why 777? the last invocation should rewrite 777 to 99

现在我的问题是-

  1. 为什么truffle调用正在创建事务,而Web3js调用却没有创建任何事务?我怎样才能让它们表现得一样
  2. 当使用truffle调用时(我的意思是当事务返回时(,如何获得方法调用的返回值

软件版本:

松露(发育(>松露版本
truffle v5.1.51(核心:5.1.51(
Solidity v0.5.16(solc js(
节点v15.1.0
Web3.js v1.2.9

Ganache:2.5.4
Nodejs:v15.1.0
Web3js:^1.3.0

Web3.js合约对象与Truffle合约对象不同。结构上有一些细微的差异,当然,因为它都是非类型化的JavaScript,所以你不知道输入或输出函数会有什么。

从历史上看,以太坊交易没有回报值。Web3.js行为早于此时间,可能不支持直接返回事务值。然而,EIP 1288记录了返回值如何通过getTransactionReceipt()receipt对象可用。

要让Web3.js修改EVM状态,您需要执行send()而不是call()。这是另一个弱类型的问题,因为不应该混淆视图和写入函数。

尝试:

console.log("Calculator adding: ", await calculatorContract.methods.add(11, 88).send({
from: '0x38e3614A5Cf95f0DBb858D9E3752Ac477DA70ccD'
}));

为了解决Truffle和Web3.js之间的差异。解决行为差异的最简单方法根本不是使用Truffle工件,而是在任何地方使用Web3.js契约。

Ps。我推荐OpenZeppelin SDK(Node.js/TypeScript(而不是Truffle。它与TypeScript类型相比更加合理,也可以在前端和后端代码中用作Web3.js的替代品。或者使用Python和Web3.py更好,因为如果你能负担得起切换一种语言的费用,这些游戏留给你的猜测游戏的空间就更小了。

最新更新