Solidity

如何使用事件從事務中檢索數據?私鏈

  • March 26, 2022

我正在使用 GETH 在私有鏈上建構和部署我的合約,它工作得很好,但不幸的是我想從交易函式返回數據,這讓我抓狂。我知道要讀取交易的返回值需要涉及solidity的事件,然後通過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() 也一樣

所以在你看來是什麼問題?我錯過了什麼嗎?

非常感謝

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 的事務被探勘時,會觸發 watch 內部的回調。這有效地允許前端從 foo 獲取返回值。

在您的情況下,您直接e在控制台中列印結果。我建議您使用e.args._add在控制台中列印預期值。

有關更多詳細資訊,請參閱本文

您缺少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也將有助於未來其他合約的可重用性。

引用自:https://ethereum.stackexchange.com/questions/48723