function initData(tx, data) {
  if (data) {
    if (typeof data === "string") {
      data = to.buffer(data);
    }
    if (Buffer.isBuffer(data)) {
      data = rlp.decode(data);
    }
    const self = tx;
    if (Array.isArray(data)) {
      if (data.length > tx._fields.length) {
        throw new Error("wrong number of fields in data");
      }

      // make sure all the items are buffers
      data.forEach((d, i) => {
        self[self._fields[i]] = ethUtil.toBuffer(d);
      });
    } else if ((typeof data === "undefined" ? "undefined" : typeof data) === "object") {
      const keys = Object.keys(data);
      tx._fields.forEach(function(field) {
        if (keys.indexOf(field) !== -1) {
          self[field] = data[field];
        }
        if (field === "gasLimit") {
          if (keys.indexOf("gas") !== -1) {
            self["gas"] = data["gas"];
          }
        } else if (field === "data") {
          if (keys.indexOf("input") !== -1) {
            self["input"] = data["input"];
          }
        }
      });

      // Set chainId value from the data, if it's there and the data didn't
      // contain a `v` value with chainId in it already. If we do have a
      // data.chainId value let's set the interval v value to it.
      if (!tx._chainId && data && data.chainId != null) {
        tx.raw[self._fields.indexOf("v")] = tx._chainId = data.chainId || 0;
      }
    } else {
      throw new Error("invalid data");
    }
  }
}