code: func readInteger(typ byte, kind reflect.Kind, b []byte) interface{} {
  	switch kind {
  	case reflect.Uint8:
  		return b[len(b)-1]
  	case reflect.Uint16:
  		return binary.BigEndian.Uint16(b[len(b)-2:])
  	case reflect.Uint32:
  		return binary.BigEndian.Uint32(b[len(b)-4:])
  	case reflect.Uint64:
  		return binary.BigEndian.Uint64(b[len(b)-8:])
  	case reflect.Int8:
  		return int8(b[len(b)-1])
  	case reflect.Int16:
  		return int16(binary.BigEndian.Uint16(b[len(b)-2:]))
  	case reflect.Int32:
  		return int32(binary.BigEndian.Uint32(b[len(b)-4:]))
  	case reflect.Int64:
  		return int64(binary.BigEndian.Uint64(b[len(b)-8:]))
  	default:
  		// the only case lefts for integer is int256/uint256.
  		// big.SetBytes can't tell if a number is negative, positive on itself.
  		// On EVM, if the returned number > max int256, it is negative.
  		ret := new(big.Int).SetBytes(b)
  		if typ == UintTy {
  			return ret
  		}
  
  		if ret.Cmp(maxInt256) > 0 {
  			ret.Add(maxUint256, big.NewInt(0).Neg(ret))
  			ret.Add(ret, big.NewInt(1))
  			ret.Neg(ret)
  		}
  		return ret
  	}
  }
docs: // reads the integer based on its kind