github.com/jonasnick/go-ethereum@v0.7.12-0.20150216215225-22176f05d387/cmd/mist/assets/ext/ethereum.js/lib/event.js (about)

     1  /*
     2      This file is part of ethereum.js.
     3  
     4      ethereum.js is free software: you can redistribute it and/or modify
     5      it under the terms of the GNU Lesser General Public License as published by
     6      the Free Software Foundation, either version 3 of the License, or
     7      (at your option) any later version.
     8  
     9      ethereum.js is distributed in the hope that it will be useful,
    10      but WITHOUT ANY WARRANTY; without even the implied warranty of
    11      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12      GNU Lesser General Public License for more details.
    13  
    14      You should have received a copy of the GNU Lesser General Public License
    15      along with ethereum.js.  If not, see <http://www.gnu.org/licenses/>.
    16  */
    17  /** @file event.js
    18   * @authors:
    19   *   Marek Kotewicz <marek@ethdev.com>
    20   * @date 2014
    21   */
    22  
    23  var abi = require('./abi');
    24  var utils = require('./utils');
    25  
    26  /// filter inputs array && returns only indexed (or not) inputs
    27  /// @param inputs array
    28  /// @param bool if result should be an array of indexed params on not
    29  /// @returns array of (not?) indexed params
    30  var filterInputs = function (inputs, indexed) {
    31      return inputs.filter(function (current) {
    32          return current.indexed === indexed;
    33      });
    34  };
    35  
    36  var inputWithName = function (inputs, name) {
    37      var index = utils.findIndex(inputs, function (input) {
    38          return input.name === name;
    39      });
    40      
    41      if (index === -1) {
    42          console.error('indexed param with name ' + name + ' not found');
    43          return undefined;
    44      }
    45      return inputs[index];
    46  };
    47  
    48  var indexedParamsToTopics = function (event, indexed) {
    49      // sort keys?
    50      return Object.keys(indexed).map(function (key) {
    51          var inputs = [inputWithName(filterInputs(event.inputs, true), key)];
    52  
    53          var value = indexed[key];
    54          if (value instanceof Array) {
    55              return value.map(function (v) {
    56                  return abi.formatInput(inputs, [v]);
    57              }); 
    58          }
    59          return abi.formatInput(inputs, [value]);
    60      });
    61  };
    62  
    63  var inputParser = function (address, signature, event) {
    64      
    65      // valid options are 'earliest', 'latest', 'offset' and 'max', as defined for 'eth.watch'
    66      return function (indexed, options) {
    67          var o = options || {};
    68          o.address = address;
    69          o.topic = [];
    70          o.topic.push(signature);
    71          if (indexed) {
    72              o.topic = o.topic.concat(indexedParamsToTopics(event, indexed));
    73          }
    74          return o;
    75      };
    76  };
    77  
    78  var getArgumentsObject = function (inputs, indexed, notIndexed) {
    79      var indexedCopy = indexed.slice();
    80      var notIndexedCopy = notIndexed.slice();
    81      return inputs.reduce(function (acc, current) {
    82          var value;
    83          if (current.indexed)
    84              value = indexed.splice(0, 1)[0];
    85          else
    86              value = notIndexed.splice(0, 1)[0];
    87  
    88          acc[current.name] = value;
    89          return acc;
    90      }, {}); 
    91  };
    92   
    93  var outputParser = function (event) {
    94      
    95      return function (output) {
    96          var result = {
    97              event: utils.extractDisplayName(event.name),
    98              number: output.number,
    99              args: {}
   100          };
   101  
   102          if (!output.topic) {
   103              return result;
   104          }
   105         
   106          var indexedOutputs = filterInputs(event.inputs, true);
   107          var indexedData = "0x" + output.topic.slice(1, output.topic.length).map(function (topic) { return topic.slice(2); }).join("");
   108          var indexedRes = abi.formatOutput(indexedOutputs, indexedData);
   109  
   110          var notIndexedOutputs = filterInputs(event.inputs, false);
   111          var notIndexedRes = abi.formatOutput(notIndexedOutputs, output.data);
   112  
   113          result.args = getArgumentsObject(event.inputs, indexedRes, notIndexedRes);
   114  
   115          return result;
   116      };
   117  };
   118  
   119  var getMatchingEvent = function (events, payload) {
   120      for (var i = 0; i < events.length; i++) {
   121          var signature = abi.eventSignatureFromAscii(events[i].name); 
   122          if (signature === payload.topic[0]) {
   123              return events[i];
   124          }
   125      }
   126      return undefined;
   127  };
   128  
   129  
   130  module.exports = {
   131      inputParser: inputParser,
   132      outputParser: outputParser,
   133      getMatchingEvent: getMatchingEvent
   134  };
   135