Массив динамических структур Solidity

когда я разрабатываю свой смарт-контракт с Solidity, я сталкиваюсь с проблемой. И ниже мой код солидности.

pragma solidity ^0.4.0;

contract RegisterContract{

event setNewUser(bytes32 name,address etherAddr, address contractAddr,uint now);
address owner;
struct User{
    bytes32 name;
    address etherAddr;
    address contractAddr;
}
User[] private users;

constructor() public{
    owner = msg.sender;
}
modifier checkOwner(){
    require(msg.sender == owner);
    _;
}
function getOwner() public view returns (address){
    return owner;
}
// for a new user create a contract 
function registerUser(bytes32 name,address etherAddr, address contractAddr) public checkOwner{
    User memory newUser;
    newUser.name = name;
    newUser.etherAddr = etherAddr;
    newUser.contractAddr = contractAddr;
    users.push(newUser);
    emit setNewUser(name,etherAddr,contractAddr,now);
}
// 
function setAddress(bytes32 name,address etherAddr, address contractAddr) public checkOwner{
    for(uint8 i=0;i<users.length;i++){
        if(users[i].name==name){
            users[i].etherAddr=etherAddr;
            users[i].contractAddr=contractAddr;
        }
    }
}
// when systems assess all user
function getUsers() public checkOwner view returns (bytes32[],address[],address[]) {
    bytes32[] memory names= new bytes32[](users.length);
    address[] memory etherAddr = new address[](users.length);
    address[] memory contractAddr = new address[](users.length);
    for(uint8 i=0;i<users.length;i++){
        names[i]= users[i].name;
        etherAddr[i] = users[i].etherAddr;
        contractAddr[i] = users[i].contractAddr;
    }
    return (names,etherAddr,contractAddr);
}
//for a user who import contract 
function getContractAddress(address etherAddr) public checkOwner view returns (bytes32,address) {
    for(uint8 i=0;i<users.length;i++){
        if(users[i].etherAddr==etherAddr){
            return (users[i].name,users[i].contractAddr);
        }
    }
}
}

Вопрос в том, когда я хочу вызвать registerUser , и когда я использую web3.js, вызывая registerContract.methods.registerUser(name,etheraddress,contractaddress), он выдает ошибку на консоли geth. Ошибка

Error: Transaction has been reverted by the EVM: { "blockHash": "0x45fe755c8c1f600108b55a12fa3bdf59dac0fe76d39883f23d15b2f9603d868d", "blockNumber": 22339, "contractAddress": null, "cumulativeGasUsed": 90000, "from": "0x5869c2317ce2df31cb1269d8028e9062ff470749", "gasUsed": 90000 , "журналыБлум": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": false, "to": "0xc249fa432a1c659e7aa4ad57e24e405215461afa", "transactionHash": "0xb52e0fabe160070597bd40192658b6f84779d52d4b295b39295d381eb0856f2d", "transactionIndex": 0, "events": {} }false, "to": "0xc249fa432a1c659e7aa4ad57e24e405215461afa", "transactionHash": "0xb52e0fabe160070597bd40192658b6f84779d52d4b295b39295d381eb0856f2d", "transactionIndex": {}false, "to": "0xc249fa432a1c659e7aa4ad57e24e405215461afa", "transactionHash": "0xb52e0fabe160070597bd40192658b6f84779d52d4b295b39295d381eb0856f2d", "transactionIndex": {}

Что-то не так, когда я обратился к структуре User и массиву push? Или есть какие-то проблемы, о которых я не знал во время разработки?

Вы проверили, является ли msg.sender владельцем? Это может быть из-за модификатора checkOwner(). Возможно, вы отправляете транзакцию от пользователя, отличного от владельца.
Лучше поделитесь кодом исполнения, потому что с контрактом все в порядке (проверил через Remix, работает)
Это не дает ответа на вопрос. Когда у вас будет достаточно репутации, вы сможете комментировать любой пост ; вместо этого предоставьте ответы, которые не требуют разъяснений от спрашивающего . - Из обзора
@vhie да, я проверил. Я также успешно запускаю ремикс, но я не знаю, почему я не могу нормально работать в своей среде.
Это, по общему признанию, не о вопросе ОП. Я думаю, стоит упомянуть, что этот подход просто потерпит неудачу, когда будет слишком много пользователей. Проблема коренится в структуре данных и проявляется в неограниченных forциклах, которые являются хорошо известным анти-паттерном.
Вы пытались увеличить лимит газа, как предложенный ответ ниже? Это также может помочь определить, как вы выполняете метод в своей среде.
@vhie спасибо за помощь, я уже решил свою проблему, проблема действительно в ограничении газа. После того, как я вызываю Mycontract.methods.Mymethod().estimateGas() и устанавливаю лимит газа в методе отправки, я решаю проблему

Ответы (1)

Я предполагаю, что вы устанавливаете слишком низкий лимит газа - попробуйте увеличить его с 90000 до 1000000 и посмотреть, пройдет ли транзакция.

Причина в том, что если бы он не работал из-за:
require(msg.sender == owner);
вы бы увидели меньше газа, потребляемого функцией (поскольку это первый код, который выполняется, и require вернет неиспользованный газ). Тот факт, что вы используете весь запас газа в размере 90 000, означает, что либо вы нажимаете ассерт (которого у вас нет), либо у вас заканчивается бензин.

Спасибо, проблема действительно в газе, я обнаружил, что мой код вызывает только Mycontract.methods.Mymethod().send(), но я не даю никаких параметров, указывающих, сколько газа следует потреблять. Кстати, знаете ли вы, если я не установлю лимит газа, каков лимит газа по умолчанию без какого-либо конкретного газа?
Для трюфеля лимит газа по умолчанию можно определить в truffle.js: