diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go
index 35e0094ddda171b88006e555093cb16eec943c5e..8018df775650d4ffb7028bc9b06712c4ab04df0a 100644
--- a/accounts/abi/abi_test.go
+++ b/accounts/abi/abi_test.go
@@ -621,14 +621,16 @@ func TestBareEvents(t *testing.T) {
 // TestUnpackEvent is based on this contract:
 //    contract T {
 //      event received(address sender, uint amount, bytes memo);
+//      event receivedAddr(address sender);
 //      function receive(bytes memo) external payable {
 //        received(msg.sender, msg.value, memo);
+//        receivedAddr(msg.sender);
 //      }
 //    }
 // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt:
 //   receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]}
 func TestUnpackEvent(t *testing.T) {
-	const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]`
+	const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
 	abi, err := JSON(strings.NewReader(abiJSON))
 	if err != nil {
 		t.Fatal(err)
@@ -656,6 +658,17 @@ func TestUnpackEvent(t *testing.T) {
 	} else {
 		t.Logf("len(data): %d; received event: %+v", len(data), ev)
 	}
+
+	type ReceivedAddrEvent struct {
+		Address common.Address
+	}
+	var receivedAddrEv ReceivedAddrEvent
+	err = abi.Unpack(&receivedAddrEv, "receivedAddr", data)
+	if err != nil {
+		t.Error(err)
+	} else {
+		t.Logf("len(data): %d; received event: %+v", len(data), receivedAddrEv)
+	}
 }
 
 func TestABI_MethodById(t *testing.T) {
diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go
index 1b480da609e4c24ea55146bda4e2e7867a336e17..512d8fdfa7a72471e1a5406895309ff3e3b97701 100644
--- a/accounts/abi/argument.go
+++ b/accounts/abi/argument.go
@@ -113,16 +113,8 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa
 	}
 	// If the output interface is a struct, make sure names don't collide
 	if kind == reflect.Struct {
-		exists := make(map[string]bool)
-		for _, arg := range arguments {
-			field := capitalise(arg.Name)
-			if field == "" {
-				return fmt.Errorf("abi: purely underscored output cannot unpack to struct")
-			}
-			if exists[field] {
-				return fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", field)
-			}
-			exists[field] = true
+		if err := requireUniqueStructFieldNames(arguments); err != nil {
+			return err
 		}
 	}
 	for i, arg := range arguments.NonIndexed() {
@@ -131,14 +123,9 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa
 
 		switch kind {
 		case reflect.Struct:
-			name := capitalise(arg.Name)
-			for j := 0; j < typ.NumField(); j++ {
-				// TODO read tags: `abi:"fieldName"`
-				if typ.Field(j).Name == name {
-					if err := set(value.Field(j), reflectValue, arg); err != nil {
-						return err
-					}
-				}
+			err := unpackStruct(value, reflectValue, arg)
+			if err != nil {
+				return err
 			}
 		case reflect.Slice, reflect.Array:
 			if value.Len() < i {
@@ -165,8 +152,20 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues []interf
 		return fmt.Errorf("abi: wrong length, expected single value, got %d", len(marshalledValues))
 	}
 	elem := reflect.ValueOf(v).Elem()
+	kind := elem.Kind()
 	reflectValue := reflect.ValueOf(marshalledValues[0])
+
+	if kind == reflect.Struct {
+		//make sure names don't collide
+		if err := requireUniqueStructFieldNames(arguments); err != nil {
+			return err
+		}
+
+		return unpackStruct(elem, reflectValue, arguments[0])
+	}
+
 	return set(elem, reflectValue, arguments.NonIndexed()[0])
+
 }
 
 // Computes the full size of an array;
@@ -278,3 +277,18 @@ func capitalise(input string) string {
 	}
 	return strings.ToUpper(input[:1]) + input[1:]
 }
+
+//unpackStruct extracts each argument into its corresponding struct field
+func unpackStruct(value, reflectValue reflect.Value, arg Argument) error {
+	name := capitalise(arg.Name)
+	typ := value.Type()
+	for j := 0; j < typ.NumField(); j++ {
+		// TODO read tags: `abi:"fieldName"`
+		if typ.Field(j).Name == name {
+			if err := set(value.Field(j), reflectValue, arg); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go
index 7a9cdacd54ab504bf9823b40b49a944d8be60b97..2e6bf7098f2c7a23aa6f91bd449afbd8f922c7f5 100644
--- a/accounts/abi/reflect.go
+++ b/accounts/abi/reflect.go
@@ -110,3 +110,19 @@ func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind,
 	}
 	return nil
 }
+
+// requireUniqueStructFieldNames makes sure field names don't collide
+func requireUniqueStructFieldNames(args Arguments) error {
+	exists := make(map[string]bool)
+	for _, arg := range args {
+		field := capitalise(arg.Name)
+		if field == "" {
+			return fmt.Errorf("abi: purely underscored output cannot unpack to struct")
+		}
+		if exists[field] {
+			return fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", field)
+		}
+		exists[field] = true
+	}
+	return nil
+}