No se pueden realizar funciones de escritura en el contrato inteligente: ¿dirección no válida?

Tengo el siguiente contrato inteligente simple...

contract SimpleStorage {
    uint storedData;
    function set(uint x) {
        storedData = x;
    }
    function get() constant returns (uint retVal) {
        return storedData;
    }
}

Que implemento con el siguiente código en la consola geth...

var source = "contract SimpleStorage...[code here]"
var compiled = web3.eth.compile.solidity(source)
var contract = web3.eth.contract(compiled.Coin.info.abiDefinition)
var storage = contract.new({from:web3.eth.accounts[0], data: compiled.SimpleStorage.code, gas: 300000})

Una vez extraído el contrato, puedo acceder a las funciones del contrato a través del objeto de almacenamiento. Supuse que podía llamar...

storage.set(10)

...para establecer la variable de datos almacenados. Sin embargo, cada vez que intento esto, aparece el error "Dirección no válida".

Estoy seguro de que esto se debe a que estoy intentando realizar una operación de escritura en el estado interno del contrato (las operaciones de lectura funcionan bien).

Necesito enviar una transacción que extraiga el nuevo estado del contrato, sin embargo, no sé cómo hacerlo.

¿Cómo puedo realizar transacciones de escritura en contratos inteligentes?

Respuestas (1)

Intenta configurar

web3.eth.defaultAccount = eth.cuentas[0]

Parece que su transacción no sabe qué cuenta usar para firmar la llamada. Cualquier llamada que cambie el estado del contrato (operación de escritura) requiere una transacción firmada.

Un enfoque alternativo sería pasar un 'objeto de transacción' como último argumento al método de contrato:

storage.set(10,{from: accounts[0]});

Edición 1:

Cuando elegí la cuenta 'de', recibí el siguiente error: 'se necesita autenticación: contraseña o desbloqueo'. Así que necesitaba ejecutar personal.unlockAccount(eth.accounts[0],"password",15000). Puede leer sobre esto en 'autenticación necesaria: contraseña o desbloqueo' Error al intentar llamar al método de contrato inteligente a través de web3 .

¡Sabía que sería sencillo! ¿Cómo haría esto sin configurar la cuenta predeterminada? Por ejemplo, si estuviera usando varias cuentas en la misma instancia de geth.
Puede llamar web3.accountsy almacenar los resultados en una matriz. Luego acceda a la matriz para la cuenta específica. Cuando llama a un método que ejecuta una transacción y necesita una cuenta, pase un objeto que contenga from:storage.set(10,{from: accounts[1]});
Esto es exactamente lo que estaba buscando. ¡Tan sencillo! Si la función tiene múltiples parámetros, ¿es solo... storage.set(a,b,c,d,{from: eth.accounts[0]})?
Sí. Consulte los documentos de la API de web3.js: github.com/ethereum/wiki/wiki/… Tenga en cuenta el objeto de transacción. Esto es lo que puede pasar como último argumento a su llamada de contrato
y como obtener el txID del resultado?
web3.eth.defaultAccount = accounts[0]debiera sereth.defaultAccount = eth.accounts[0]
Esto funcionó para mí también. Solo quiero compartir cómo cambié mi llamada para obtener una respuesta basada en los comentarios anteriores en web3.js en la terminal Mac: Llamada original: contractInstance.getStep() . Nueva llamada: contractInstance.getStep({from: web3.eth.accounts[0]}).