Длина массива структур всегда равна 1

Это контракт, который я призываю createPнажатьPost

    struct Post {
        uint256 amt;
        bool isActive;
        address owner;
    }

    Post[] public posts;

    function createP(uint256 amt) public payable returns(uint a) {
        posts.push(Post({
            amt: amt,
            isActive: false,
            owner: msg.sender
        }));
        return (posts.length);
    }
    function getPostLength() returns(uint a){
        return (posts.length);
    }

Код трюфеля

        MyContract.deployed()
        .then(async instance => {
            const weiSpend = web3.toWei(2, "ether");
            var id = await instance.createP.call(10,{
                from: accounts[0],
                value: weiSpend
            });
        var id2 = await instance.createP.call(50,{
          from: accounts[1],
          value: weiSpend
        });
        var id3 = await instance.createP.call(100,{
          from: accounts[2],
          value: weiSpend
        });                        
        var last = await instance.getPostLength.call();
        console.log(id3.toString()); // returns 1 instead of 3
        console.log(last.toString()); // returns 0 instead of 3
        });

Ответы (1)

Вы можете вызвать функцию в смарт-контракте двумя разными способами:

  1. Вы можете callэто сделать, и в этом случае транзакция не будет отправлена ​​в сеть Ethereum. Результат вычисляется локально (на любом узле, к которому вы подключены) и возвращается. Это быстро и бесплатно, но никакое состояние не может быть изменено.
  2. Вы можете отправить транзакцию, в этом случае вы должны заплатить за газ, и транзакция отправляется в сеть. Как только он превращается в блок, его мутации вступают в силу.

Поскольку вы пытаетесь изменить переменную состояния posts, вам необходимо отправить транзакцию. Но instance.createP.callвместо этого просто вызывает его, как будто он не мутирует состояние. Используйте instance.createP.sendTransactionвместо этого.