#ethereum #solidity #web3js
#ethereum #солидность #web3js
Вопрос:
Вот как выглядит мой контракт —
pragma solidity >=0.4.25 <0.8.0;
contract Calculator {
uint public resu<
event Added(address caller, uint a, uint b, uint res);
constructor() public {
result = 777;
}
function add(uint a, uint b) public returns (uint, address) {
result = a b;
emit Added(msg.sender, a, b, result);
return (result, msg.sender);
}
}
Вышеуказанный контракт развернут в тестовой сети Ropsten. И я пытаюсь вызвать add(...)
функцию с транзакцией. И мой код выглядит так —
const accountAddress = rtUtil.getAccountAddress();
const accountPk = Buffer.from(rtUtil.getAccountAddressPk(), "hex");
const contract = await rtUtil.getCalculatorContract();
const data = contract.methods.add(3, 74).encodeABI();
const web3 = rtUtil.getWeb3();
const taxCount = await web3.eth.getTransactionCount(accountAddress);
const txObject = {
nonce: web3.utils.toHex(taxCount),
to: rtUtil.getCalculatorContractAddress(),
value: web3.utils.toHex(web3.utils.toWei('0', 'ether')),
gasLimit: web3.utils.toHex(2100000),
gasPrice: web3.utils.toHex(web3.utils.toWei('6', 'gwei')),
data: data
};
const commmon = new Common({chain: "ropsten", hardfork: "petersburg"});
const tx = Transaction.fromTxData(txObject, {commmon});
tx.sign(accountPk);
const serializedTx = tx.serialize();
const raw = web3.utils.toHex(serializedTx);
const transaction = await web3.eth.sendSignedTransaction(raw);
И когда я запускаю код, я получаю ошибку —
Uncaught Error: Returned error: invalid sender
Process exited with code 1
Мои версии Nodejs v15.1.0
И мои package.json
зависимости —
"dependencies": {
"@ethereumjs/common": "^2.0.0",
"@ethereumjs/tx": "^3.0.0",
"@truffle/contract": "^4.2.30",
"@truffle/hdwallet-provider": "^1.2.0",
"web3": "^1.3.0"
}
Кто-нибудь может сказать мне, что я делаю не так?
Заранее спасибо.
Ответ №1:
В вашем txObject вам необходимо указать идентификатор цепочки.
Добавьте идентификатор цепочки Ropsten, 3 в txObject.
const txObject = {
nonce: web3.utils.toHex(taxCount),
to: rtUtil.getCalculatorContractAddress(),
value: web3.utils.toHex(web3.utils.toWei('0', 'ether')),
gasLimit: web3.utils.toHex(2100000),
gasPrice: web3.utils.toHex(web3.utils.toWei('6', 'gwei')),
data: data,
chainId: web3.utils.toHex(3)
};
Комментарии:
1. это работает в моем случае, но могло бы дать больше объяснений, почему
chainId
должно быть 3? Спасибо2. @neo это связано с простой защитой от повторных атак, она была введена в EIP-155 . Вы также можете проверить chainlist.org для получения списка идентификаторов цепочки для каждой сети.
Ответ №2:
Вам необходимо включить from
в свой txObject:
const txObject = {
from: accountAddress,
nonce: web3.utils.toHex(taxCount),
to: rtUtil.getCalculatorContractAddress(),
value: web3.utils.toHex(web3.utils.toWei('0', 'ether')),
gasLimit: web3.utils.toHex(2100000),
gasPrice: web3.utils.toHex(web3.utils.toWei('6', 'gwei')),
data: data
};
Комментарии:
1. Я не думаю, что это проблема. Поскольку транзакция подписана, so from может быть извлечен из подписи. Я тоже пробовал с from, но проблема не устранена.