Как использовать события для извлечения данных из транзакции? ЧАСТНАЯ СЕТЬ

я использую GETH для архитектуры и развертывания моего контракта в частной цепочке, и он работает довольно хорошо, но, к сожалению, я хочу вернуть данные из функции транзакции, и это сводит меня с ума. Я знаю, что для чтения возвращаемого значения транзакций необходимо задействовать события солидности, а затем через WEB3 мы можем их прочитать. Я покажу свои подробные шаги для чтения событий, но ничего не работает. Будем очень благодарны за любую помощь. Это код, который мне нужно собрать:

This is the event declaration right above the contract constructor

event Accessed(string _msg,address _add, uint _time);


function transfer(bytes32 _ID) public returns (address)
{
    // Only the current owner can transfer the token.
    if (ID == _ID)
        {    
                owner = msg.sender;
                taddr.push(msg.sender); //taddr is an array used for storing address of whoever call the
                                        //transfer function
                ttime.push(now);        //same but it stores the timestamp
                Accessed("someone executed the transfer function",owner,now);
                return(owner); 
        } 
}
 function getOwners() view public returns (address[],uint[]) //this should print the two above arrays and return them
{

     return (taddr,ttime);

}

Так что я хочу в основном получить 2 массива в качестве возврата или, по крайней мере, прочитать каждый вызов функции transaction().

После развертывания я использую

var myContract = web3.eth.contract([ABI]);
var meta = myContract.at("address");
var Transfer = meta.Accessed({}, {fromBlock: 0, toBlock: 'latest'});
Transfer.watch(function(err, e) {
   if (err) {
      console.log(err);
} else {
      console.log("new Transfer executed from", e);
}
});

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

 {
 callbacks: [],
 filterId: "0x1b2e43d107ba5d1426df7243a74e6c04",
 getLogsCallbacks: [],
 implementation: {
 getLogs: function(),
 newFilter: function(),
 poll: function(),
 uninstallFilter: function()
 },
 options: {
 address: "0x18776b68d09660c4ddbfda8e71f67906c7147edf",
 from: undefined,
 fromBlock: "0x0",
 to: undefined,
 toBlock: "latest",
 topics:["0xa938469e072f18fc99f2e[...]", 
 null, null, null]
 },
 pollFilters: [],
 requestManager: {
 polls: {
 0x3ef60ce0d464242fac329bd3e1720427: {
    data: {...},
    id: "0x3ef60ce0d464242fac329bd3e1720427",
    callback: function(error, messages),
    uninstall: function()
  },
  0x80efdb3c4df0b69c53f1f9ce47d527bb: {
    data: {...},
    id: "0x80efdb3c4df0b69c53f1f9ce47d527bb",
    callback: function(error, messages),
    uninstall: function()
  },
  0xb62a9e7d2148f67acf56a96aca3046f2: {
    data: {...},
    id: "0xb62a9e7d2148f67acf56a96aca3046f2",
    callback: function(error, messages),
    uninstall: function()
  },
  0xe63a8aea7e45a2576b0852dd129c37d7: {
    data: {...},
    id: "0xe63a8aea7e45a2576b0852dd129c37d7",
    callback: function(error, messages),
    uninstall: function()
  }
},
provider: {
  newAccount: function(),
  openWallet: function(),
  send: function github.com/ethereum/go-ethereum/console.(*bridge).Send-fm(),
  sendAsync: function github.com/ethereum/go-ethereum/console.(*bridge).Send-fm(),
  sign: function(),
  unlockAccount: function()
},
timeout: {},
poll: function(),
reset: function(keepIsSyncing),
send: function(data),
sendAsync: function(data, callback),
sendBatch: function(data, callback),
setProvider: function(p),
startPolling: function(data, pollId, callback, uninstall),
stopPolling: function(pollId)
},
formatter: function(),
get: function(callback),
stopWatching: function(callback),
watch: function(callback)
}

То же самое происходит с event.get()

ТАК по вашему в чем проблема? Я что-то пропустил?

Большое спасибо

Ответы (2)

contract ExampleContract {
  event ReturnValue(address indexed _from, int256 _value);

function foo(int256 _value) returns (int256) {
    ReturnValue(msg.sender, _value);
    return _value;
  }
}

Затем внешний интерфейс может получить возвращаемое значение:

var exampleEvent = exampleContract.ReturnValue({_from: web3.eth.coinbase});
exampleEvent.watch(function(err, result) {
  if (err) {
    console.log(err)
    return;
  }
  console.log(result.args._value)
  // check that result.args._from is web3.eth.coinbase then
  // display result.args._value in the UI and call    
  // exampleEvent.stopWatching()
})


exampleContract.foo.sendTransaction(2, {from: web3.eth.coinbase})

Когда транзакция, вызывающая foo, добывается, будет запущен обратный вызов внутри часов. Это эффективно позволяет внешнему интерфейсу получать возвращаемые значения из foo.

В вашем случае вы напрямую печатаете результат eв консоли. Я рекомендую вам использовать e.args._addдля печати предполагаемого значения в консоли.

Обратитесь к этой статье для более подробной информации

Спасибо, сэр, за разъяснение и пример. Я попробовал ваш пример, и он сработал, тот же подход, примененный к моему, не работает. Это заставило меня немного изменить код, возможно, что-то не так. Кстати, ваша проблема немного отличается, потому что ваша транзакция не является правильной транзакцией, а является чем-то большим, чем вызов. Вы не изменяете состояние EVM, поэтому возвращаемое значение полностью доступно для возврата. Напротив, мое событие создается внутри SET, поэтому возврат не может быть выполнен. Есть ли у вас какие-либо предложения, которые я могу попробовать на моем коде, чтобы увидеть, работает ли он?

Вы пропустили ключевое слово emitперед своим мероприятием. Вот так:

function transfer(bytes32 _ID) public returns (address) {
    // Only the current owner can transfer the token.
    if (ID == _ID) {    
      owner = msg.sender;
      taddr.push(msg.sender);
      ttime.push(now);        //same but it stores the timestamp
      emit Accessed("someone executed the transfer function",owner,now);
      
      return(owner); 
    } 
}

Кроме того, block.timestampобычно следует использовать вместо now. nowофициально объявлен устаревшим в версии 0.7.0, но даже при использовании более ранней версии использование block.timestampпоможет с повторным использованием для других контрактов в будущем.

Наиболее часто используемой версией Solidity в 2018 году была версия 0.4, где использование emitне требовалось. Если и была ошибка, то что-то другое.