¿Cómo llamar a una función de cambio de estado con web3.js (navegador) y nodo remoto?

Contrato de Solidez:

contract MyContract {
    bytes32 public product;
    uint public amount;

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

Javascript web3js (sin 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>

Esto funciona cuando tengo ganache-cli ejecutándose, pero no en una red de prueba (por ejemplo, Ropsten). En una red de prueba, solo puedo obtener funciones, pero ¿cómo llamo a una función de establecimiento? ¿Que me estoy perdiendo aqui?

cual es el siloContract? ¿Y qué versión de web3 estás usando?
Esto es del contrato original, lo cambió a MyContract. estoy usando 0.20.6
¿Su código JS se ve bien, pero su método de contrato no tiene un cuerpo? Necesitaría ether en su cuenta ( coinbase) para poder llamar transacciones en ropsten.

Respuestas (3)

Las transacciones deben firmarse con la clave privada de la cuenta de envío.

Está utilizando Infura como su proveedor web3 y le está pidiendo que envíe una transacción por usted. No puede hacer eso porque no conoce la clave privada de su cuenta.

Deberá escribir código para firmar la transacción usted mismo o (el enfoque más típico) usar un proveedor web3 como MetaMask en el navegador. MetaMask conserva las claves privadas del usuario y firma transacciones en su nombre (después de solicitar su aprobación).

Gracias por la respuesta. Quiero firmarlo, pero no sé cómo. ¿Tiene un enlace con información o puede poner más detalles en su respuesta?

Según el documento , debe cambiar el contractInstance.setOrder(web3.toHex('ProductName'),3000); método para

Envía una transacción: (Tu caso)

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

Si solo desea llamar a una función que no actualiza el estado (y no cuesta nada):

contractInstance.product.call(param1, , function(err, result){ ... }) 
Gracias. Pero mi web3 (v0.20.6) no me muestra methodsdespués de escribir la instancia en la consola de un navegador. Además, ¿no tengo que proporcionar una clave de alguna manera para firmar una transacción de cambio de estado? from: ethaddressno puede ser suficiente o lo es?
Oh, lo siento, pensé que estabas usando web3> 1, actualicé mi comentario de acuerdo con tu versión.
Gracias, pero ¿dónde firmo la transacción? No uso metamask, solo infura y tengo que firmar los datos de alguna manera.

Debe usar Web3js para firmar su transacción en el lado del cliente antes de enviarla a Infura:

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

Para más detalles ver documentación