syntax = "proto3";
package ethermint.evm.v1alpha1;

import "gogoproto/gogo.proto";

option go_package = "github.com/cosmos/ethermint/x/evm/types";

// Params defines the EVM module parameters
message Params {
  option (gogoproto.goproto_stringer) = false;

  // evm_denom represents the token denomination used to run the EVM state
  // transitions.
  string evm_denom = 1 [(gogoproto.moretags) = "yaml:\"evm_denom\""];
  // enable_create toggles state transitions that use the vm.Create function
  bool enable_create = 2 [(gogoproto.moretags) = "yaml:\"enable_create\""];
  // enable_call toggles state transitions that use the vm.Call function
  bool enable_call = 3 [(gogoproto.moretags) = "yaml:\"enable_call\""];
  // extra_eips defines the additional EIPs for the vm.Config
  repeated int64 extra_eips = 4 [(gogoproto.customname) = "ExtraEIPs", (gogoproto.moretags) = "yaml:\"extra_eips\""];
}

// ChainConfig defines the Ethereum ChainConfig parameters using sdk.Int values
// instead of big.Int.
//
// NOTE 1: Since empty/uninitialized Ints (i.e with a nil big.Int value) are
// parsed to zero, we need to manually specify that negative Int values will be
// considered as nil. See getBlockValue for reference.
//
// NOTE 2: This type is not a configurable Param since the SDK does not allow
// for validation against a previous stored parameter values or the current
// block height (retrieved from context). If you want to update the config
// values, use an software upgrade procedure.
message ChainConfig {
  // Homestead switch block (< 0 no fork, 0 = already homestead)
  string homestead_block = 1 [
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"homestead_block\"",
    (gogoproto.nullable)   = false
  ];
  // TheDAO hard-fork switch block (< 0 no fork)
  string dao_fork_block = 2 [
    (gogoproto.customname) = "DAOForkBlock",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"dao_fork_block\"",
    (gogoproto.nullable)   = false
  ];
  // Whether the nodes supports or opposes the DAO hard-fork
  bool dao_fork_support = 3
      [(gogoproto.customname) = "DAOForkSupport", (gogoproto.moretags) = "yaml:\"dao_fork_support\""];
  // EIP150 implements the Gas price changes
  // (https://github.com/ethereum/EIPs/issues/150) EIP150 HF block (< 0 no fork)
  string eip150_block = 4 [
    (gogoproto.customname) = "EIP150Block",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"eip150_block\"",
    (gogoproto.nullable)   = false
  ];
  // EIP150 HF hash (needed for header only clients as only gas pricing changed)
  string eip150_hash = 5 [(gogoproto.customname) = "EIP150Hash", (gogoproto.moretags) = "yaml:\"byzantium_block\""];
  // EIP155Block HF block
  string eip155_block = 6 [
    (gogoproto.customname) = "EIP155Block",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"eip155_block\"",
    (gogoproto.nullable)   = false
  ];
  // EIP158 HF block
  string eip158_block = 7 [
    (gogoproto.customname) = "EIP158Block",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"eip158_block\"",
    (gogoproto.nullable)   = false
  ];
  // Byzantium switch block (< 0 no fork, 0 = already on byzantium)
  string byzantium_block = 8 [
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"byzantium_block\"",
    (gogoproto.nullable)   = false
  ];
  // Constantinople switch block (< 0 no fork, 0 = already activated)
  string constantinople_block = 9 [
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"constantinople_block\"",
    (gogoproto.nullable)   = false
  ];
  // Petersburg switch block (< 0 same as Constantinople)
  string petersburg_block = 10 [
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"petersburg_block\"",
    (gogoproto.nullable)   = false
  ];
  // Istanbul switch block (< 0 no fork, 0 = already on istanbul)
  string istanbul_block = 11 [
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"istanbul_block\"",
    (gogoproto.nullable)   = false
  ];
  // Eip-2384 (bomb delay) switch block (< 0 no fork, 0 = already activated)
  string muir_glacier_block = 12 [
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"muir_glacier_block\"",
    (gogoproto.nullable)   = false
  ];
// Berlin switch block (< 0 = no fork, 0 = already on berlin)
    string berlin_block = 13 [
      (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
      (gogoproto.moretags)   = "yaml:\"berlin_block\"",
      (gogoproto.nullable)   = false
    ];
  // YOLO v3: Gas repricings
  string yolo_v3_block = 14 [
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"yolo_v3_block\"",
    (gogoproto.nullable)   = false
  ];
  // EWASM switch block (< 0 no fork, 0 = already activated)
  string ewasm_block = 15 [
    (gogoproto.customname) = "EWASMBlock",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"ewasm_block\"",
    (gogoproto.nullable)   = false
  ];
  // Catalyst switch block (< 0 = no fork, 0 = already on catalyst)
  string catalyst_block = 16 [
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
    (gogoproto.moretags)   = "yaml:\"catalyst_block\"",
    (gogoproto.nullable)   = false
  ];
}

// State represents a single Storage key value pair item.
message State {
  string key   = 1;
  string value = 2;
}

// TransactionLogs define the logs generated from a transaction execution
// with a given hash. It it used for import/export data as transactions are not
// persisted on blockchain state after an upgrade.
message TransactionLogs {
  string       hash = 1;
  repeated Log logs = 2;
}

// Log represents an protobuf compatible Ethereum Log that defines a contract
// log event. These events are generated by the LOG opcode and stored/indexed by
// the node.
message Log {
  // Consensus fields:

  // address of the contract that generated the event
  string address = 1;
  // list of topics provided by the contract.
  repeated string topics = 2;
  // supplied by the contract, usually ABI-encoded
  bytes data = 3;

  // Derived fields. These fields are filled in by the node
  // but not secured by consensus.

  // block in which the transaction was included
  uint64 block_number = 4 [(gogoproto.jsontag) = "blockNumber"];
  // hash of the transaction
  string tx_hash = 5 [(gogoproto.jsontag) = "transactionHash"];
  // index of the transaction in the block
  uint64 tx_index = 6 [(gogoproto.jsontag) = "transactionIndex"];
  // hash of the block in which the transaction was included
  string block_hash = 7 [(gogoproto.jsontag) = "blockHash"];
  // index of the log in the block
  uint64 index = 8 [(gogoproto.jsontag) = "logIndex"];

  // The Removed field is true if this log was reverted due to a chain
  // reorganisation. You must pay attention to this field if you receive logs
  // through a filter query.
  bool removed = 9;
}

// TxReceipt defines the receipt type stored in KV for each EVM transaction.
message TxReceipt {
  option (gogoproto.goproto_getters) = false;

  string    hash        = 1;
  string    from        = 2;
  TxData   data        = 3;
  TxResult result      = 4;
  uint64   index       = 5;
  uint64   block_height = 6;
  string    block_hash   = 7;
}

// TxResult stores results of Tx execution.
message TxResult {
  option (gogoproto.goproto_getters) = false;

  // contract_address contains the ethereum address of the created contract (if
  // any). If the state transition is an evm.Call, the contract address will be
  // empty.
  string contract_address = 1 [(gogoproto.moretags) = "yaml:\"contract_address\""];
  // bloom represents the bloom filter bytes
  bytes bloom = 2;
  // tx_logs contains the transaction hash and the proto-compatible ethereum
  // logs.
  TransactionLogs tx_logs = 3 [(gogoproto.moretags) = "yaml:\"tx_logs\"", (gogoproto.nullable) = false];
  // ret defines the bytes from the execution.
  bytes ret = 4;
  // reverted flag is set to true when the call has been reverted
  bool reverted = 5;
  // gas_used notes the amount of gas consumed while execution
  uint64 gas_used = 6;
}

// TxData implements the Ethereum transaction data structure. It is used
// solely as intended in Ethereum abiding by the protocol.
message TxData {
  option (gogoproto.goproto_getters) = false;

  // destination EVM chain ID
  bytes chain_id = 1 [
    (gogoproto.customname) = "ChainID",
    (gogoproto.jsontag) = "chainID"
  ];
  // nonce corresponds to the account nonce (transaction sequence).
  uint64 nonce = 2;
  // price defines the unsigned integer value of the gas price in bytes.
  bytes gas_price = 3 [(gogoproto.customname) = "GasPrice"];
  // gas defines the gas limit defined for the transaction.
  uint64 gas = 4 [(gogoproto.customname) = "GasLimit"];
  // hex formatted address of the recipient
  string  to  = 5;
  // value defines the unsigned integer value of the transaction amount.
  bytes value = 6 [(gogoproto.customname) = "Amount"];
  // input defines the data payload bytes of the transaction.
  bytes input = 7;
  repeated AccessTuple accesses = 8 [
    (gogoproto.castrepeated) = "AccessList",
    (gogoproto.jsontag) = "accessList",
    (gogoproto.nullable)   = false
  ];
  // v defines the signature value
  bytes v = 9;
  // r defines the signature value
  bytes r = 10;
  // s define the signature value
  bytes s = 11;
}

message BytesList {
  option (gogoproto.goproto_getters) = false;

  repeated bytes bytes = 1;
}

// AccessTuple is the element type of an access list.
message AccessTuple {
  option (gogoproto.goproto_getters) = false;

  // hex formatted ethereum address
  string    address = 1;
  // hex formatted hashes of the storage keys
	repeated  string storage_keys = 2 [(gogoproto.jsontag) = "storageKeys"];
}