Solidity

如何使用事件找到函式的結果?

  • January 2, 2020

考慮以下基本的solidity智能合約

    event BattleResult(string result,uint playerResult, uint enemyResult);
    mapping(address => uint)playerChoice;

    function setChoice(uint _number)public {
        playerChoice[msg.sender] = _number
       }

    function battle(address _target) public {
     playerValue = playerChoice[msg.sender];
     enemyValue = playerChoice[_target];
     if(playerValue > enemyValue){
      emit Battleresult("win",playerValue,enemyValue);
      }
     else if(playerValue < enemyValue){
      emit Battleresult("lose",playerValue,enemyValue);
      }
     else if(playerValue == enemyValue){
      emit Battleresult("draw",playerValue,enemyValue);
      }

}

在這個基本範例中,玩家選擇一個數字並開始戰鬥。不要介意安全措施以及玩家可以在進入戰鬥之前檢查對手的價值這一事實。

我遇到的問題是,當我在前端設置戰鬥時,我嘗試向玩家展示結果(無論發出什麼:贏、輸或平)。我遇到的問題是,僅針對特定玩家過濾資訊是不可能的,而且每次我嘗試做某事時,我都無法在控制台中得到任何結果。

我試過

SmartcontractInstance.events.BattleResult({}, {fromBlock: 0}, function(error,event){
     console.log(event);
   })
 }

這使我可以獲取所有過去的事件。但是,有沒有辦法只從特定的戰鬥中獲得結果?

例如,我是否應該更改我的 Solidity 智能合約並為每個功能添加

returns(string,uint,uint)

我嘗試做的一件事是檢查地址並查看它是否與發件人匹配,然後將其推送到數組中,我會簡單地顯示最後一個索引(這聽起來效率低下,但也許只是我的看法)。

let result =[];
   SmartcontractInstance.events.BattleResult({}, {fromBlock: 0}, function(error,event){
     for(let i=0; i<event.length;i++){
       if(event.args.address == account[0]){
         result.push(event.args.address);
       }
     }
   })
console.log(result);  /// i'm getting an empty array unfortunately

例如,我是否應該更改我的 Solidity 智能合約並為每個功能添加

返回(字元串,uint,uint)

那是不行的。返回值對其他合約可見,但在外部不可見。

我遇到的問題是,僅針對特定玩家過濾資訊是不可能的

您可以過濾事件,但您必須:

  • 在日誌中包含要過濾的數據
  • 將其定義為indexed

例如event LogName(address indexed player, ...);

然後,您可以在觀察者端配置事件過濾器。

重要的是要記住客戶將如何依賴事件日誌,以便他們需要的一切都在那裡。由於合約是不可變的,任何客戶需要的一切。

一個好的起點是包含理論上從日誌中重建合約狀態歷史所需的所有資訊。

查看此處以獲取使用帶有索引值的日誌的範例。 如何返回特定參數的事件?

希望能幫助到你。

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