Транзакция Ethereum выдает ошибку «неверный отправитель»

#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, но проблема не устранена.