Как получить данные ответа Ethers.js

Твердость:

      function ping() public view returns ( uint ) {
    return 999999999;
}
function ping2() public returns ( uint ) {
    return 999999999;
}

Javascript Ethers.js:

      (await contract.ping()).toString();  //-> 999999999  ( correct ) 
(await contract.ping2()).toString(); //-> [object Object] ( ?? )

Почему ping2 возвращает [Object Object]? Как получить данные из ping2?

Также:

      (await contract.sendTransaction(txObj)).toString(); //-> [object Object] ( ?? )

Почему использование sendTransaction также возвращает [объект Object]?

3 ответа

Вот отличное решение от Force Hero с использованием Events.

В двух словах:

      const tx = await contract.transfer(...args); // 100ms
const rc = await tx.wait(); // 0ms, as tx is already confirmed
const event = rc.events.find(event => event.event === 'Transfer');
const [from, to, value] = event.args;
console.log(from, to, value);

(ждать contract.ping()).toString(); // -> 999999999 (правильно)

ping()это функция - вы можете просто вызвать ее, не создавая транзакции. Таким образом, ethers.js не создает транзакцию, а просто возвращает результат вызова.


(ждать contract.ping2()).toString(); //-> [объект Object] (??)

Почему использование sendTransaction также возвращает [объект Object]?

регулярный publicфункция. Это говорит о том, что вам нужно создать транзакцию для ее выполнения (хотя в этом случае она не вносит никаких изменений в состояние, поэтому это также может быть функция просмотра).

Ethers.js возвращает данные транзакции вместо возвращаемого значения функции контракта, когда вы создаете транзакцию.

Есть несколько способов прочитать значения, созданные транзакцией с помощью Ethers.js.

  • В таком случае, ping2() не вносит никаких изменений в состояние и даже не считывает данные блокчейна, поэтому это может быть pureфункция. Если бы он читал данные блокчейна, это был бы view функция ... В обоих случаях ethers.jsвозвращает результат вызова функции (не tx).

  • Транзакция с сеттером и вызов геттера .

            contract MyContract {
        uint256 value;
    
        function setValue(uint256 _value) public {
            value = _value;
        }
    
        function getValue() public view returns (uint256) {
            return value;
        }
    }
    

    Сначала вы создаете транзакцию, которая выполняет setValue() функция, а затем вы вызываете getValue() (без транзакции, поэтому он возвращает значение в вашем JS).

  • Чтение журналов событий, созданных вашей транзакцией

            event Transfer(address from, address to, uint256 amount);
    
    function transfer(address _to, uint256 _amount) public {
        emit Transfer(msg.sender, _to, _amount);
    }
    

    Вы можете получить о квитанциютранзакции, которая также содержит журналы событий (в данном случае Transfer событие и его значения).

при вызове я получаю такой результат, но не могу преобразовать его в число:

ZoneAwarePromise{__zone_symbol__state: null, __zone_symbol__value: Array(0)} __ zone_symbol__state: true__zone_symbol__value: BigNumber{_hex: '0x01', _isBigNumber: true} Symbol (Symbol.species SymbolT (Symbol.StringT): (... ..)[[Prototype]]: Объект

Другие вопросы по тегам