diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go
index 01603b21796a7415f02440d88d3c8fd3f10becd9..b0765e7db064886a8f7c85321d266b47ef634b70 100644
--- a/accounts/abi/abi.go
+++ b/accounts/abi/abi.go
@@ -20,6 +20,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"io"
+	"math/big"
 	"reflect"
 	"strings"
 
@@ -116,11 +117,80 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) {
 	return append(method.Id(), arguments...), nil
 }
 
+// toGoSliceType prses the input and casts it to the proper slice defined by the ABI
+// argument in T.
+func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
+	index := i * 32
+	// The slice must, at very least be large enough for the index+32 which is exactly the size required
+	// for the [offset in output, size of offset].
+	if index+32 > len(output) {
+		return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), index+32)
+	}
+
+	// first we need to create a slice of the type
+	var refSlice reflect.Value
+	switch t.Type.T {
+	case IntTy, UintTy, BoolTy: // int, uint, bool can all be of type big int.
+		refSlice = reflect.ValueOf([]*big.Int(nil))
+	case AddressTy: // address must be of slice Address
+		refSlice = reflect.ValueOf([]common.Address(nil))
+	case HashTy: // hash must be of slice hash
+		refSlice = reflect.ValueOf([]common.Hash(nil))
+	default: // no other types are supported
+		return nil, fmt.Errorf("abi: unsupported slice type %v", t.Type.T)
+	}
+	// get the offset which determines the start of this array ...
+	offset := int(common.BytesToBig(output[index : index+32]).Uint64())
+	if offset+32 > len(output) {
+		return nil, fmt.Errorf("abi: cannot marshal in to go slice: offset %d would go over slice boundary (len=%d)", len(output), offset+32)
+	}
+
+	slice := output[offset:]
+	// ... starting with the size of the array in elements ...
+	size := int(common.BytesToBig(slice[:32]).Uint64())
+	slice = slice[32:]
+	// ... and make sure that we've at the very least the amount of bytes
+	// available in the buffer.
+	if size*32 > len(slice) {
+		return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), offset+32+size*32)
+	}
+
+	// reslice to match the required size
+	slice = slice[:(size * 32)]
+	for i := 0; i < size; i++ {
+		var (
+			inter        interface{}             // interface type
+			returnOutput = slice[i*32 : i*32+32] // the return output
+		)
+
+		// set inter to the correct type (cast)
+		switch t.Type.T {
+		case IntTy, UintTy:
+			inter = common.BytesToBig(returnOutput)
+		case BoolTy:
+			inter = common.BytesToBig(returnOutput).Uint64() > 0
+		case AddressTy:
+			inter = common.BytesToAddress(returnOutput)
+		case HashTy:
+			inter = common.BytesToHash(returnOutput)
+		}
+		// append the item to our reflect slice
+		refSlice = reflect.Append(refSlice, reflect.ValueOf(inter))
+	}
+
+	// return the interface
+	return refSlice.Interface(), nil
+}
+
 // toGoType parses the input and casts it to the proper type defined by the ABI
 // argument in T.
 func toGoType(i int, t Argument, output []byte) (interface{}, error) {
-	index := i * 32
+	// we need to treat slices differently
+	if t.Type.Kind == reflect.Slice {
+		return toGoSlice(i, t, output)
+	}
 
+	index := i * 32
 	if index+32 > len(output) {
 		return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), index+32)
 	}
diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go
index db33face92b59c5dd894d4dfe6f53196d1c64a86..a0f0d1034843724fd260d0bed098d1367d778583 100644
--- a/accounts/abi/abi_test.go
+++ b/accounts/abi/abi_test.go
@@ -688,12 +688,15 @@ func TestUnmarshal(t *testing.T) {
 	{ "name" : "bytes", "const" : false, "outputs": [ { "type": "bytes" } ] },
 	{ "name" : "fixed", "const" : false, "outputs": [ { "type": "bytes32" } ] },
 	{ "name" : "multi", "const" : false, "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] },
+	{ "name" : "addressSliceSingle", "const" : false, "outputs": [ { "type": "address[]" } ] },
+	{ "name" : "addressSliceDouble", "const" : false, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] },
 	{ "name" : "mixedBytes", "const" : true, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]`
 
 	abi, err := JSON(strings.NewReader(definition))
 	if err != nil {
 		t.Fatal(err)
 	}
+	buff := new(bytes.Buffer)
 
 	// marshal int
 	var Int *big.Int
@@ -718,7 +721,6 @@ func TestUnmarshal(t *testing.T) {
 	}
 
 	// marshal dynamic bytes max length 32
-	buff := new(bytes.Buffer)
 	buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020"))
 	buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020"))
 	bytesOut := common.RightPadBytes([]byte("hello"), 32)
@@ -837,4 +839,71 @@ func TestUnmarshal(t *testing.T) {
 	if !bytes.Equal(fixed, out[1].([]byte)) {
 		t.Errorf("expected %x, got %x", fixed, out[1])
 	}
+
+	// marshal address slice
+	buff.Reset()
+	buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020")) // offset
+	buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // size
+	buff.Write(common.Hex2Bytes("0000000000000000000000000100000000000000000000000000000000000000"))
+
+	var outAddr []common.Address
+	err = abi.Unpack(&outAddr, "addressSliceSingle", buff.Bytes())
+	if err != nil {
+		t.Fatal("didn't expect error:", err)
+	}
+
+	if len(outAddr) != 1 {
+		t.Fatal("expected 1 item, got", len(outAddr))
+	}
+
+	if outAddr[0] != (common.Address{1}) {
+		t.Errorf("expected %x, got %x", common.Address{1}, outAddr[0])
+	}
+
+	// marshal multiple address slice
+	buff.Reset()
+	buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040")) // offset
+	buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000080")) // offset
+	buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // size
+	buff.Write(common.Hex2Bytes("0000000000000000000000000100000000000000000000000000000000000000"))
+	buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // size
+	buff.Write(common.Hex2Bytes("0000000000000000000000000200000000000000000000000000000000000000"))
+	buff.Write(common.Hex2Bytes("0000000000000000000000000300000000000000000000000000000000000000"))
+
+	var outAddrStruct struct {
+		A []common.Address
+		B []common.Address
+	}
+	err = abi.Unpack(&outAddrStruct, "addressSliceDouble", buff.Bytes())
+	if err != nil {
+		t.Fatal("didn't expect error:", err)
+	}
+
+	if len(outAddrStruct.A) != 1 {
+		t.Fatal("expected 1 item, got", len(outAddrStruct.A))
+	}
+
+	if outAddrStruct.A[0] != (common.Address{1}) {
+		t.Errorf("expected %x, got %x", common.Address{1}, outAddrStruct.A[0])
+	}
+
+	if len(outAddrStruct.B) != 2 {
+		t.Fatal("expected 1 item, got", len(outAddrStruct.B))
+	}
+
+	if outAddrStruct.B[0] != (common.Address{2}) {
+		t.Errorf("expected %x, got %x", common.Address{2}, outAddrStruct.B[0])
+	}
+	if outAddrStruct.B[1] != (common.Address{3}) {
+		t.Errorf("expected %x, got %x", common.Address{3}, outAddrStruct.B[1])
+	}
+
+	// marshal invalid address slice
+	buff.Reset()
+	buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000100"))
+
+	err = abi.Unpack(&outAddr, "addressSliceSingle", buff.Bytes())
+	if err == nil {
+		t.Fatal("expected error:", err)
+	}
 }
diff --git a/accounts/abi/type.go b/accounts/abi/type.go
index 18cd04672c25788e15ef93572b64e93061031597..b7ce6a13bb6a43f1be7a44785979eb9cffc5ed7f 100644
--- a/accounts/abi/type.go
+++ b/accounts/abi/type.go
@@ -113,7 +113,6 @@ func NewType(t string) (typ Type, err error) {
 	case "real": // TODO
 		typ.Kind = reflect.Invalid
 	case "address":
-		typ.Kind = reflect.Slice
 		typ.Type = address_t
 		typ.Size = 20
 		typ.T = AddressTy
@@ -125,12 +124,12 @@ func NewType(t string) (typ Type, err error) {
 			typ.Size = 32
 		}
 	case "hash":
-		typ.Kind = reflect.Slice
+		typ.Kind = reflect.Array
 		typ.Size = 32
 		typ.Type = hash_t
 		typ.T = HashTy
 	case "bytes":
-		typ.Kind = reflect.Slice
+		typ.Kind = reflect.Array
 		typ.Type = byte_ts
 		typ.Size = vsize
 		if vsize == 0 {