diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go
index 635dc43fe48a30c7e4932e28b4151a1e944babc7..b84fd463ad268bf0417f0f4b88366b4e50fba8a9 100644
--- a/accounts/abi/abi.go
+++ b/accounts/abi/abi.go
@@ -37,6 +37,7 @@ type Executer func(datain []byte) []byte
 // packs data accordingly.
 type ABI struct {
 	Methods map[string]Method
+	Events  map[string]Event
 }
 
 // JSON returns a parsed ABI interface and error if it failed.
@@ -149,14 +150,37 @@ func (abi ABI) Call(executer Executer, name string, args ...interface{}) interfa
 }
 
 func (abi *ABI) UnmarshalJSON(data []byte) error {
-	var methods []Method
-	if err := json.Unmarshal(data, &methods); err != nil {
+	var fields []struct {
+		Type    string
+		Name    string
+		Const   bool
+		Indexed bool
+		Inputs  []Argument
+		Outputs []Argument
+	}
+
+	if err := json.Unmarshal(data, &fields); err != nil {
 		return err
 	}
 
 	abi.Methods = make(map[string]Method)
-	for _, method := range methods {
-		abi.Methods[method.Name] = method
+	abi.Events = make(map[string]Event)
+	for _, field := range fields {
+		switch field.Type {
+		// empty defaults to function according to the abi spec
+		case "function", "":
+			abi.Methods[field.Name] = Method{
+				Name:    field.Name,
+				Const:   field.Const,
+				Inputs:  field.Inputs,
+				Outputs: field.Outputs,
+			}
+		case "event":
+			abi.Events[field.Name] = Event{
+				Name:   field.Name,
+				Inputs: field.Inputs,
+			}
+		}
 	}
 
 	return nil
diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go
index d514fb8c7238d58a91c646c1b76c8522abd84356..000c118f89bfd4baa019f7adf4eabff50be31c58 100644
--- a/accounts/abi/abi_test.go
+++ b/accounts/abi/abi_test.go
@@ -31,25 +31,25 @@ import (
 
 const jsondata = `
 [
-	{ "name" : "balance", "const" : true },
-	{ "name" : "send", "const" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }
+	{ "type" : "function", "name" : "balance", "const" : true },
+	{ "type" : "function", "name" : "send", "const" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }
 ]`
 
 const jsondata2 = `
 [
-	{ "name" : "balance", "const" : true },
-	{ "name" : "send", "const" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] },
-	{ "name" : "test", "const" : false, "inputs" : [ { "name" : "number", "type" : "uint32" } ] },
-	{ "name" : "string", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "string" } ] },
-	{ "name" : "bool", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "bool" } ] },
-	{ "name" : "address", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "address" } ] },
-	{ "name" : "string32", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "string32" } ] },
-	{ "name" : "uint64[2]", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[2]" } ] },
-	{ "name" : "uint64[]", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[]" } ] },
-	{ "name" : "foo", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" } ] },
-	{ "name" : "bar", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] },
-	{ "name" : "slice", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] },
-	{ "name" : "slice256", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint256[2]" } ] }
+	{ "type" : "function", "name" : "balance", "const" : true },
+	{ "type" : "function", "name" : "send", "const" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] },
+	{ "type" : "function", "name" : "test", "const" : false, "inputs" : [ { "name" : "number", "type" : "uint32" } ] },
+	{ "type" : "function", "name" : "string", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "string" } ] },
+	{ "type" : "function", "name" : "bool", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "bool" } ] },
+	{ "type" : "function", "name" : "address", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "address" } ] },
+	{ "type" : "function", "name" : "string32", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "string32" } ] },
+	{ "type" : "function", "name" : "uint64[2]", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[2]" } ] },
+	{ "type" : "function", "name" : "uint64[]", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[]" } ] },
+	{ "type" : "function", "name" : "foo", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" } ] },
+	{ "type" : "function", "name" : "bar", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] },
+	{ "type" : "function", "name" : "slice", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] },
+	{ "type" : "function", "name" : "slice256", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint256[2]" } ] }
 ]`
 
 func TestType(t *testing.T) {
@@ -96,7 +96,7 @@ func TestReader(t *testing.T) {
 			},
 			"send": Method{
 				"send", false, []Argument{
-					Argument{"amount", Uint256},
+					Argument{"amount", Uint256, false},
 				}, nil,
 			},
 		},
@@ -238,7 +238,7 @@ func TestTestAddress(t *testing.T) {
 func TestMethodSignature(t *testing.T) {
 	String, _ := NewType("string")
 	String32, _ := NewType("string32")
-	m := Method{"foo", false, []Argument{Argument{"bar", String32}, Argument{"baz", String}}, nil}
+	m := Method{"foo", false, []Argument{Argument{"bar", String32, false}, Argument{"baz", String, false}}, nil}
 	exp := "foo(string32,string)"
 	if m.Sig() != exp {
 		t.Error("signature mismatch", exp, "!=", m.Sig())
@@ -250,7 +250,7 @@ func TestMethodSignature(t *testing.T) {
 	}
 
 	uintt, _ := NewType("uint")
-	m = Method{"foo", false, []Argument{Argument{"bar", uintt}}, nil}
+	m = Method{"foo", false, []Argument{Argument{"bar", uintt, false}}, nil}
 	exp = "foo(uint256)"
 	if m.Sig() != exp {
 		t.Error("signature mismatch", exp, "!=", m.Sig())
@@ -367,8 +367,8 @@ func ExampleJSON() {
 
 func TestBytes(t *testing.T) {
 	const definition = `[
-	{ "name" : "balance", "const" : true, "inputs" : [ { "name" : "address", "type" : "bytes20" } ] },
-	{ "name" : "send", "const" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }
+	{ "type" : "function", "name" : "balance", "const" : true, "inputs" : [ { "name" : "address", "type" : "bytes20" } ] },
+	{ "type" : "function", "name" : "send", "const" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }
 ]`
 
 	abi, err := JSON(strings.NewReader(definition))
@@ -396,10 +396,8 @@ func TestBytes(t *testing.T) {
 
 func TestReturn(t *testing.T) {
 	const definition = `[
-	{ "name" : "balance", "const" : true, "inputs" : [], "outputs" : [ { "name": "", "type": "hash" } ] },
-	{ "name" : "name", "const" : true, "inputs" : [], "outputs" : [ { "name": "", "type": "address" } ] }
-
-]`
+	{ "type" : "function", "name" : "balance", "const" : true, "inputs" : [], "outputs" : [ { "name": "", "type": "hash" } ] },
+	{ "type" : "function", "name" : "name", "const" : true, "inputs" : [], "outputs" : [ { "name": "", "type": "address" } ] }]`
 
 	abi, err := JSON(strings.NewReader(definition))
 	if err != nil {
@@ -424,3 +422,39 @@ func TestReturn(t *testing.T) {
 		t.Errorf("expected type common.Address, got %T", r)
 	}
 }
+
+func TestDefaultFunctionParsing(t *testing.T) {
+	const definition = `[{ "name" : "balance" }]`
+
+	abi, err := JSON(strings.NewReader(definition))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if _, ok := abi.Methods["balance"]; !ok {
+		t.Error("expected 'balance' to be present")
+	}
+}
+
+func TestBareEvents(t *testing.T) {
+	const definition = `[
+	{ "type" : "event", "name" : "balance" },
+	{ "type" : "event", "name" : "name" }]`
+
+	abi, err := JSON(strings.NewReader(definition))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(abi.Events) != 2 {
+		t.Error("expected 2 events")
+	}
+
+	if _, ok := abi.Events["balance"]; !ok {
+		t.Error("expected 'balance' event to be present")
+	}
+
+	if _, ok := abi.Events["name"]; !ok {
+		t.Error("expected 'name' event to be present")
+	}
+}
diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go
index 8907b29793d5141fb7a5c1a73a16a4ad2375e9ae..188203a5d12f9b2b3094921933f4420314f42c56 100644
--- a/accounts/abi/argument.go
+++ b/accounts/abi/argument.go
@@ -24,8 +24,9 @@ import (
 // Argument holds the name of the argument and the corresponding type.
 // Types are used when packing and testing arguments.
 type Argument struct {
-	Name string
-	Type Type
+	Name    string
+	Type    Type
+	Indexed bool // indexed is only used by events
 }
 
 func (a *Argument) UnmarshalJSON(data []byte) error {
diff --git a/accounts/abi/event.go b/accounts/abi/event.go
new file mode 100644
index 0000000000000000000000000000000000000000..7c4e092ea5a49cf781dbded14396d6865a32f39f
--- /dev/null
+++ b/accounts/abi/event.go
@@ -0,0 +1,44 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package abi
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/crypto"
+)
+
+// Event is an event potentially triggered by the EVM's LOG mechanism. The Event
+// holds type information (inputs) about the yielded output
+type Event struct {
+	Name   string
+	Inputs []Argument
+}
+
+// Id returns the canonical representation of the event's signature used by the
+// abi definition to identify event names and types.
+func (e Event) Id() common.Hash {
+	types := make([]string, len(e.Inputs))
+	i := 0
+	for _, input := range e.Inputs {
+		types[i] = input.Type.String()
+		i++
+	}
+	return common.BytesToHash(crypto.Sha3([]byte(fmt.Sprintf("%v(%v)", e.Name, strings.Join(types, ",")))))
+}
diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..34a7a1684eda791d9c61527d3934312669a1fbbc
--- /dev/null
+++ b/accounts/abi/event_test.go
@@ -0,0 +1,40 @@
+package abi
+
+import (
+	"strings"
+	"testing"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/crypto"
+)
+
+func TestEventId(t *testing.T) {
+	var table = []struct {
+		definition   string
+		expectations map[string]common.Hash
+	}{
+		{
+			definition: `[
+			{ "type" : "event", "name" : "balance", "inputs": [{ "name" : "in", "type": "uint" }] },
+			{ "type" : "event", "name" : "check", "inputs": [{ "name" : "t", "type": "address" }, { "name": "b", "type": "uint256" }] }
+			]`,
+			expectations: map[string]common.Hash{
+				"balance": crypto.Sha3Hash([]byte("balance(uint256)")),
+				"check":   crypto.Sha3Hash([]byte("check(address,uint256)")),
+			},
+		},
+	}
+
+	for _, test := range table {
+		abi, err := JSON(strings.NewReader(test.definition))
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		for name, event := range abi.Events {
+			if event.Id() != test.expectations[name] {
+				t.Errorf("expected id to be %x, got %x", test.expectations[name], event.Id())
+			}
+		}
+	}
+}
diff --git a/accounts/abi/type.go b/accounts/abi/type.go
index 8f0238fc996f1f9348c7c310e7025b6a5ff2a01e..32f761ef0bb8afeb676f4727f2f3a3d8d43297ff 100644
--- a/accounts/abi/type.go
+++ b/accounts/abi/type.go
@@ -218,5 +218,5 @@ func (t Type) pack(v interface{}) ([]byte, error) {
 		}
 	}
 
-	return nil, fmt.Errorf("ABI: bad input given %T", value.Kind())
+	return nil, fmt.Errorf("ABI: bad input given %v", value.Kind())
 }