Проблема с установкой значения uint на ноль

Я сделал несколько смарт-контрактов в браузере Solidity. Вот мой код:

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;  
    }
}

Когда я использую "JavaScript VM" все нормально, но когда я компилирую контракт с Injected Web3 возникает проблема.

Добавление пользователя (с помощью add_user) все в порядке, но когда я пытаюсь удалить пользователя, я получаю сообщение об ошибке: обратный вызов не содержит результата Ошибка: Нет газа

После некоторого теста я предположил, что ошибка возникает, когда я пытаюсь установить значение uint равным нулю.

Затем я пытаюсь изменить 0 в

userRegister[_hc].active=0;

с 9 (или другим целым числом)

userRegister[_hc].active=9; 

И все работает нормально.

Итак, кто-нибудь может сказать мне, что не так с установкой значения uint на 0? И как я могу переустановить переменную uint в ноль? Спасибо

Я проверил ваш код, и это интересная проблема!
попробуйте установить uint на uint256
@BadrBellaj - установка uint на uint256 не сработала.
Я попытался установить «активный» как логическую переменную, затем в функции «add_user» я установил userRegister[_hc].active=true; И в функции удаления я установил userRegister[_hc].active=false; Но когда я вызываю удаление, возникает та же проблема.
Некоторое обсуждение этой проблемы на reddit.com/r/ethdev/comments/5m6j1q/…
у меня та же проблема, я думаю, причина в том, что когда uint установлен на 0, требуется некоторое извлечение, чтобы оптимизировать хранение этого uint (точно так же, как удаление), тогда потребуется еще немного газа, как бы функция оценки газа не могла не вычислить его. если прибавить газ то все ок.

Ответы (1)

Резюме

Это каким-то образом кажется проблемой взаимодействия Browser Solidity с файлами geth. Когда я развертываю контракт и выполняю транзакции непосредственно в geth, контракт работает так, как ожидалось.

@PietroR91, пожалуйста, отправьте свой код как проблему в github Browser Solidity. Если вы не можете этого сделать, я могу сделать это позже.



Подробности

Окружающая среда

Ошибка в Browser Solidity была проверена с прагмой и компилятором ^0.4.0, ^0.4.4и ^0.4.7.

gethЯ использую стабильную версию 1.5.5 для OS/X .

Модифицированный исходный код

Вот ваш исходный код, измененный добавлением getUser(...)для проверки значений данных в сопоставлении и некоторыми незначительными изменениями форматирования:

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;
    }
}

Браузер Solidity — развертывание и выполнениеadd_user(...)

введите описание изображения здесь

Browser Solidity — попытка выполнитьremove(...)

При попытке выполнить remove(...)в Browser Solidity callback contain no result Error: Intrinsic gas too lowотображается сообщение.

введите описание изображения здесь

Браузер Solidity — развертывание Web3

Ниже приведен код развертывания Web3 из 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);
    }
 })

Развертывание контракта вgeth

Я вставляю код Web3 Deploy из предыдущего раздела в свою gethконсоль разработки:

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

Выполнение функций вgeth

Затем я выполнил следующие функции в 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
}

Проверка правильности выполнения функции:

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

Давайте теперь выполним remove(...)функцию с проблемой:

> 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
}

Проверка правильности выполнения функции:

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



Интересное наблюдение

Если я изменю remove(...), чтобы добавить следующее:

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

Я могу выполнить функцию в Browser Solidity, но возвращаемый результат getUser(...)показывает, что значение active не изменяется с 1 на 0.

Выполнение измененной remove(...)функции в браузере Solidity

На следующем экране показано remove(...)успешное выполнение функции в Browser Solidity:

введите описание изображения здесь

Ниже приводится квитанция о транзакции в 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
}

На следующем экране показан второй вызов getUser(...), результаты которого не изменились. activeпо-прежнему 1вместо ожидаемого 0:

введите описание изображения здесь