Problema al establecer el valor de uint en cero

Hice algunos contratos inteligentes con el navegador Solidity, este es mi código:

pragma solidity ^0.4.0;

contract Test {
    struct User {
        string name;
        string surname;
        uint active;
    }

    mapping(bytes32 => User) public userRegister;

    function add_user(string _name, string _surname) {
        bytes32 _hc=sha3(_name, _surname);
        User p = userRegister[_hc];  

        p.name=_name;
        p.surname=_surname;
        p.active=1;
    }

    function remove(string _name, string _surname)  {
        bytes32 _hc=sha3(_name, _surname);
        userRegister[_hc].active=0;  
    }

    function active(string _name, string _surname)  {
        bytes32 _hc=sha3(_name, _surname);
        userRegister[_hc].active=1;  
    }
}

Cuando uso "JavaScript VM" todo está bien, pero cuando compilo el contrato con Injected Web3 hay un problema.

Agregar un usuario (con add_user) está bien, pero cuando trato de eliminar un usuario, aparece un error: la devolución de llamada no contiene ningún resultado Error: Sin gasolina

Después de algunas pruebas, supuse que se da un error cuando intento establecer un valor uint en cero.

Luego trato de cambiar el 0 en

userRegister[_hc].active=0;

con 9 (u otro número int)

userRegister[_hc].active=9; 

Y todo funciona bien.

Entonces, ¿alguien puede decirme qué tiene de malo establecer un valor uint en 0? ¿Y cómo puedo restablecer una variable uint a cero? Gracias

¡He probado tu código y es un problema interesante!
intente establecer uint en uint256
@BadrBellaj: configurar uint en uint256 no funcionó.
Intenté establecer "activo" como una variable bool, luego en la función "add_user" configuré userRegister[_hc].active=true; Y en la función eliminar, configuré userRegister[_hc].active=false; Pero cuando llamo a eliminarlo tengo el mismo problema..
Algunas discusiones sobre este tema en reddit.com/r/ethdev/comments/5m6j1q/…
tengo el mismo problema, creo que la razón es que cuando un uint se establece en 0, se necesita un movimiento de extracción para optimizar el almacenamiento de este uint (al igual que eliminar), luego tomará un poco más de gasolina, sin embargo, la función de estimación de gas podría No lo calcules. si subes el gas, entonces todo está bien.

Respuestas (1)

Resumen

Esto de alguna manera parece ser un problema con la interacción de Browser Solidity con geth. Cuando implemento el contrato y ejecuto las transacciones directamente en geth, el contrato funciona como se esperaba.

@PietroR91, envíe su código como un problema en Browser Solidity github. Si no puedes hacerlo, puedo hacerlo más tarde.



Detalles

Ambiente

El error en Browser Solidity ha sido verificado con el pragma y el compilador siendo ^0.4.0, ^0.4.4y ^0.4.7.

El gethentorno que estoy usando es la versión 1.5.5 estable en OS/X.

Código fuente modificado

Aquí está su código fuente, modificado por la adición de getUser(...)para verificar los valores de los datos en el mapeo y algunos cambios de formato menores:

pragma solidity ^0.4.0;

contract Test {
    struct User {
        string name;
        string surname;
        uint active;
    }

    mapping (bytes32 => User) public userRegister;

    function add_user(string _name, string _surname) {
        bytes32 _hc = sha3(_name, _surname);
        User p = userRegister[_hc];
        p.name = _name;
        p.surname = _surname;
        p.active = 1;
    }

    function remove(string _name, string _surname)  {
        bytes32 _hc = sha3(_name, _surname);
        userRegister[_hc].active = 0;
    }

    function active(string _name, string _surname)  {
        bytes32 _hc=sha3(_name, _surname);
        userRegister[_hc].active = 1;
    }

    function getUser(string _name, string _surname) constant
      returns (string name, string surname, uint256 active) {
        bytes32 _hc = sha3(_name, _surname);
        name = userRegister[_hc].name;
        surname = userRegister[_hc].surname;
        active = userRegister[_hc].active;
    }
}

Solidez del navegador: implementar y ejecutaradd_user(...)

ingrese la descripción de la imagen aquí

Solidez del navegador: intento de ejecuciónremove(...)

Al intentar ejecutar remove(...)en Browser Solidity, callback contain no result Error: Intrinsic gas too lowse muestra el mensaje.

ingrese la descripción de la imagen aquí

Solidez del navegador - Web3 Deploy

El siguiente es el código de implementación de Web3 de Browser Solidity:

var testContract = web3.eth.contract([{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"userRegister","outputs":[{"name":"name","type":"string"},{"name":"surname","type":"string"},{"name":"active","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_surname","type":"string"}],"name":"add_user","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_surname","type":"string"}],"name":"remove","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"},{"name":"_surname","type":"string"}],"name":"getUser","outputs":[{"name":"name","type":"string"},{"name":"surname","type":"string"},{"name":"active","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_surname","type":"string"}],"name":"active","outputs":[],"payable":false,"type":"function"}]);
var test = testContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '0x606060405234610000575b610aae806100196000396000f300606060405263ffffffff60e060020a60003504166312f8ed308114610050578063400462fa1461016b57806344590a7e146101fd57806383e6858f1461028f57806398f5be8714610418575b610000565b34610000576100606004356104aa565b604080519081018290526060808252845460026000196101006001841615020190911604908201819052819060208201906080830190879080156100e55780601f106100ba576101008083540402835291602001916100e5565b820191906000526020600020905b8154815290600101906020018083116100c857829003601f168201915b50508381038252855460026000196101006001841615020190911604808252602090910190869080156101595780601f1061012e57610100808354040283529160200191610159565b820191906000526020600020905b81548152906001019060200180831161013c57829003601f168201915b50509550505050505060405180910390f35b34610000576101fb600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f89358b018035918201839004830284018301909452808352979998810197919650918201945092508291508401838280828437509496506104c595505050505050565b005b34610000576101fb600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f89358b018035918201839004830284018301909452808352979998810197919650918201945092508291508401838280828437509496506106d995505050505050565b005b346100005761031f600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f89358b0180359182018390048302840183019094528083529799988101979196509182019450925082915084018382808284375094965061079895505050505050565b6040805190810182905260608082528451908201528351819060208083019160808401918801908083838215610370575b80518252602083111561037057601f199092019160209182019101610350565b505050905090810190601f16801561039c5780820380516001836020036101000a031916815260200191505b50838103825285518152855160209182019187019080838382156103db575b8051825260208311156103db57601f1990920191602091820191016103bb565b505050905090810190601f1680156104075780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34610000576101fb600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f89358b018035918201839004830284018301909452808352979998810197919650918201945092508291508401838280828437509496506109bf95505050505050565b005b60006020819052908152604090206002810154600182019083565b6000600083836040518083805190602001908083835b602083106104fa5780518252601f1990920191602091820191016104db565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106105425780518252601f199092019160209182019101610523565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405180910390209150600060008360001916600019168152602001908152602001600020905083816000019080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106105dd57805160ff191683800117855561060a565b8280016001018555821561060a579182015b8281111561060a5782518255916020019190600101906105ef565b5b5061062b9291505b808211156106275760008155600101610613565b5090565b505082816001019080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061067b57805160ff19168380011785556106a8565b828001600101855582156106a8579182015b828111156106a857825182559160200191906001019061068d565b5b506106c99291505b808211156106275760008155600101610613565b5090565b5050600160028201555b50505050565b600082826040518083805190602001908083835b6020831061070c5780518252601f1990920191602091820191016106ed565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106107545780518252601f199092019160209182019101610735565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120600081815291829052928120600201555093505050505b505050565b602060405190810160405280600081525060206040519081016040528060008152506000600085856040518083805190602001908083835b602083106107ef5780518252601f1990920191602091820191016107d0565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106108375780518252601f199092019160209182019101610818565b518151600019602094850361010090810a8201928316921993909316919091179092526040805196909401869003862060008181528085528590208054601f600260018316159095029095011692909204928301849004840287018401909452818652929850939650909450919250508301828280156108f85780601f106108cd576101008083540402835291602001916108f8565b820191906000526020600020905b8154815290600101906020018083116108db57829003601f168201915b50505060008481526020818152604091829020600190810180548451600260001994831615610100029490940190911692909204601f81018490048402830184019094528382529599509493509091508301828280156109995780601f1061096e57610100808354040283529160200191610999565b820191906000526020600020905b81548152906001019060200180831161097c57829003601f168201915b50505060008481526020819052604090206002015492955091935050505b509250925092565b600082826040518083805190602001908083835b602083106109f25780518252601f1990920191602091820191016109d3565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310610a3a5780518252601f199092019160209182019101610a1b565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912060008181529182905292902060016002909101555093505050505b5050505600a165627a7a72305820a6692301b30e1302f9b8c77813503eb5f8e127531e5903cffcf70070af2e9a7a0029', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

Implementación del contrato engeth

Pego el código de implementación de Web3 de la sección anterior en mi gethconsola de desarrollo:

I0106 08:17:04.067480 internal/ethapi/api.go:1045] Tx(0x2ce868c7e3377f4330ef847747b471c5ff27384b67e973fff2c86f3547316db6) created: 0x22718021ba1f0ce28931c3d0653f624c6b409763
null [object Object]
undefined
...
null [object Object]
Contract mined! address: 0x22718021ba1f0ce28931c3d0653f624c6b409763 transactionHash: 0x2ce868c7e3377f4330ef847747b471c5ff27384b67e973fff2c86f3547316db6

Ejecutando las funciones engeth

Luego ejecuté las siguientes funciones en geth:

> test.add_user("test_name", "test_surname", {from: eth.accounts[0], gas: 400000});
I0106 08:19:07.999559 internal/ethapi/api.go:1047] Tx(0xda430dd968ce3537ed29b4e57ff6f10a4feb6fb674ac1f50ac5684368b9415c1) to: 0x22718021ba1f0ce28931c3d0653f624c6b409763
"0xda430dd968ce3537ed29b4e57ff6f10a4feb6fb674ac1f50ac5684368b9415c1"
...
> eth.getTransactionReceipt("0xda430dd968ce3537ed29b4e57ff6f10a4feb6fb674ac1f50ac5684368b9415c1")
{
  blockHash: "0x02e8f2b1385bafb4336a8057640967763e05ad430c47a169ce0512f5e3bc9859",
  blockNumber: 5878,
  contractAddress: null,
  cumulativeGasUsed: 85340,
  from: "0x000d1009bd8f0b1301cc5edc28ed1222a3ce671e",
  gasUsed: 85340,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x28b34cf11c24cc9dc72ea47539b556ce8266fa5d4bed8910da24783019e6f9cb",
  to: "0x22718021ba1f0ce28931c3d0653f624c6b409763",
  transactionHash: "0xda430dd968ce3537ed29b4e57ff6f10a4feb6fb674ac1f50ac5684368b9415c1",
  transactionIndex: 0
}

Comprobando que la función se ejecutó correctamente:

> test.getUser("test_name", "test_surname");
["test_name", "test_surname", 1]

Ahora ejecutemos la remove(...)función con el problema:

> test.remove("test_name", "test_surname", {from: eth.accounts[0], gas: 400000});
I0106 08:22:30.226885 internal/ethapi/api.go:1047] Tx(0x684c27aac5ff70c97c374646de9ec376ad2a2b67c7e0205445ed208b1b95b30b) to: 0x22718021ba1f0ce28931c3d0653f624c6b409763
"0x684c27aac5ff70c97c374646de9ec376ad2a2b67c7e0205445ed208b1b95b30b"
...
> eth.getTransactionReceipt("0x684c27aac5ff70c97c374646de9ec376ad2a2b67c7e0205445ed208b1b95b30b")
{
  blockHash: "0x895f68c8d0aa3adf2ec86e22ddc4f7ca9b185252258374430ff96988646ae7a0",
  blockNumber: 5899,
  contractAddress: null,
  cumulativeGasUsed: 14828,
  from: "0x000d1009bd8f0b1301cc5edc28ed1222a3ce671e",
  gasUsed: 14828,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x4f21b21ed39fc110bc8c2e9e5ac3be3576c1733c59660f728bd180273dd16210",
  to: "0x22718021ba1f0ce28931c3d0653f624c6b409763",
  transactionHash: "0x684c27aac5ff70c97c374646de9ec376ad2a2b67c7e0205445ed208b1b95b30b",
  transactionIndex: 0
}

Comprobando que la función se ejecutó correctamente:

> test.getUser("test_name", "test_surname");
["test_name", "test_surname", 0]



Una observación interesante

Si modifico remove(...)para agregar lo siguiente:

function remove(string _name, string _surname)  {
    bytes32 _hc = sha3(_name, _surname);
    userRegister[_hc].name = _name;
    userRegister[_hc].surname = _surname;
    userRegister[_hc].active = 0;
}

Puedo ejecutar la función en Browser Solidity, pero el resultado getUser(...)muestra que el valor de activo no se modifica de 1 a 0.

Ejecutando la remove(...)función Modified en Browser Solidity

La siguiente pantalla muestra la remove(...)función que se ejecuta con éxito en Browser Solidity:

ingrese la descripción de la imagen aquí

El siguiente es el recibo de la transacción en geth:

> eth.getTransactionReceipt("0x59734b415f6e1094f57b07579cfaba53325321f1cee9512c84c4b257ed222d3c")
{
  blockHash: "0x91949c01a0bf15a8d8cf558b9e9afcda686855669960c5aaf46069d9d75d5c82",
  blockNumber: 5949,
  contractAddress: null,
  cumulativeGasUsed: 85468,
  from: "0x000d1009bd8f0b1301cc5edc28ed1222a3ce671e",
  gasUsed: 85468,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x2bf9db658636a8de8af1d4f171c8b8ea97d11bf55592d0fce67b69f3947719a6",
  to: "0x49472fa49f6e3e84c0c038416f000eaeddb5c891",
  transactionHash: "0x59734b415f6e1094f57b07579cfaba53325321f1cee9512c84c4b257ed222d3c",
  transactionIndex: 0
}

La siguiente pantalla muestra la segunda invocación de getUser(...)donde los resultados no se modifican. activesigue siendo 1en lugar de lo esperado 0:

ingrese la descripción de la imagen aquí