Как вызвать функцию изменения состояния с помощью web3.js (браузер) и удаленного узла?

Контракт солидности:

contract MyContract {
    bytes32 public product;
    uint public amount;

    function setOrder(bytes32 _product, uint _reorderAmount,) public returns (bool success);   
}

Javascript web3js (без node.js):

<script src="./web3.min.js"></script>
<script>
web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/key"));
web3.eth.defaultAccount = "0x...address of my account...";
var myContract = web3.eth.contract([...abi...]);
var contractInstance = myContract.at('0x...contract address...');
contractInstance.setOrder(web3.toHex('ProductName'),3000);
</script>

Это работает, когда у меня работает ganache-cli, но не в тестовой сети (например, Ropsten). В тестовой сети я могу использовать только геттерные функции, но как мне вызвать сеттерную функцию? Что мне здесь не хватает?

что такое siloContract? а какую версию web3 используете?
Это из оригинального контракта, изменил его на MyContract. Я использую 0.20.6
Ваш код JS выглядит нормально, но у вашего метода контракта нет тела? Вам понадобится эфир в вашем аккаунте( coinbase), чтобы иметь возможность вызывать транзакции на ropsten.

Ответы (3)

Транзакции должны быть подписаны закрытым ключом отправляющей учетной записи.

Вы используете Infura в качестве провайдера web3 и просите его отправить вам транзакцию. Он не может этого сделать, потому что не знает закрытого ключа вашей учетной записи.

Вам нужно будет либо написать код для подписи транзакции самостоятельно, либо (более типичный подход) использовать поставщика web3, такого как MetaMask, в браузере. MetaMask хранит закрытые ключи пользователя и подписывает транзакции от его имени (после запроса подтверждения).

Спасибо за ответ. Хочу подписать, но не знаю как. У вас есть ссылка с информацией или вы можете добавить больше деталей в свой ответ?

Согласно документу , вы должны изменить contractInstance.setOrder(web3.toHex('ProductName'),3000); метод на

Отправить транзакцию: (Ваш случай)

contractInstance.setOrder.sendTransaction(web3.toHex('ProductName'),3000, { from: ethaddress }, function(err, result){ ... })

Если вы хотите просто вызвать функцию, которая не обновляет состояние (и ничего не стоит):

contractInstance.product.call(param1, , function(err, result){ ... }) 
Спасибо. Но мой web3 (v0.20.6) не показывает меня methodsпосле того, как я записываю экземпляр в консоль браузера. Также мне не нужно каким-то образом предоставлять ключ, чтобы подписать транзакцию изменения состояния? from: ethaddressне может быть достаточно или это?
Извините, я думал, что вы используете web3> 1, я обновил свой комментарий в соответствии с вашей версией
Спасибо, а где подписать транзакцию? метамасками не пользуюсь, только инфура и надо как-то подписывать данные

Вам необходимо использовать Web3js для подписи транзакции на стороне клиента перед ее отправкой в ​​Infura:

web3.eth.sendSignedTransaction(
  web3.eth.accounts.signTransaction(
    {
      to: contractInstance.address,
      data: contractInstance.methods.setOrder.encodeABI(
        web3.toHex('ProductName'),3000),
      gas: 100000
    }));

Подробнее см. документацию