diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go
index b0765e7db064886a8f7c85321d266b47ef634b70..9ef7c0f0d31682b7a6d09e673e1f0323d8698271 100644
--- a/accounts/abi/abi.go
+++ b/accounts/abi/abi.go
@@ -186,7 +186,7 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
 // argument in T.
 func toGoType(i int, t Argument, output []byte) (interface{}, error) {
 	// we need to treat slices differently
-	if t.Type.Kind == reflect.Slice {
+	if t.Type.IsSlice {
 		return toGoSlice(i, t, output)
 	}
 
diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go
index a0f0d1034843724fd260d0bed098d1367d778583..a1b3e62d9559498d56b0c68526eeb55289a9ee81 100644
--- a/accounts/abi/abi_test.go
+++ b/accounts/abi/abi_test.go
@@ -59,7 +59,7 @@ func TestType(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-	if typ.Kind != reflect.Ptr {
+	if typ.Kind != reflect.Uint {
 		t.Error("expected uint32 to have kind Ptr")
 	}
 
@@ -67,8 +67,8 @@ func TestType(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-	if typ.Kind != reflect.Slice {
-		t.Error("expected uint32[] to have type slice")
+	if !typ.IsSlice {
+		t.Error("expected uint32[] to be slice")
 	}
 	if typ.Type != ubig_t {
 		t.Error("expcted uith32[] to have type uint64")
@@ -78,13 +78,13 @@ func TestType(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-	if typ.Kind != reflect.Slice {
-		t.Error("expected uint32[2] to have kind slice")
+	if !typ.IsSlice {
+		t.Error("expected uint32[2] to be slice")
 	}
 	if typ.Type != ubig_t {
 		t.Error("expcted uith32[2] to have type uint64")
 	}
-	if typ.Size != 2 {
+	if typ.SliceSize != 2 {
 		t.Error("expected uint32[2] to have a size of 2")
 	}
 }
@@ -149,10 +149,6 @@ func TestTestNumbers(t *testing.T) {
 		t.Errorf("expected send( ptr ) to throw, requires *big.Int instead of *int")
 	}
 
-	if _, err := abi.Pack("send", 1000); err != nil {
-		t.Error("expected send(1000) to cast to big")
-	}
-
 	if _, err := abi.Pack("test", uint32(1000)); err != nil {
 		t.Error(err)
 	}
@@ -204,7 +200,7 @@ func TestTestSlice(t *testing.T) {
 		t.FailNow()
 	}
 
-	slice := make([]byte, 2)
+	slice := make([]uint64, 2)
 	if _, err := abi.Pack("uint64[2]", slice); err != nil {
 		t.Error(err)
 	}
@@ -214,6 +210,21 @@ func TestTestSlice(t *testing.T) {
 	}
 }
 
+func TestImplicitTypeCasts(t *testing.T) {
+	abi, err := JSON(strings.NewReader(jsondata2))
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	slice := make([]uint8, 2)
+	_, err = abi.Pack("uint64[2]", slice)
+	expStr := "`uint64[2]` abi: cannot use type uint8 as type uint64"
+	if err.Error() != expStr {
+		t.Errorf("expected %v, got %v", expStr, err)
+	}
+}
+
 func TestMethodSignature(t *testing.T) {
 	String, _ := NewType("string")
 	String32, _ := NewType("string32")
diff --git a/accounts/abi/type.go b/accounts/abi/type.go
index b7ce6a13bb6a43f1be7a44785979eb9cffc5ed7f..5a5a5ac49e654d67c238b5e6f8e2eae8b331e5be 100644
--- a/accounts/abi/type.go
+++ b/accounts/abi/type.go
@@ -40,6 +40,9 @@ const (
 
 // Type is the reflection of the supported argument type
 type Type struct {
+	IsSlice   bool
+	SliceSize int
+
 	Kind       reflect.Kind
 	Type       reflect.Type
 	Size       int
@@ -47,6 +50,11 @@ type Type struct {
 	stringKind string // holds the unparsed string for deriving signatures
 }
 
+var (
+	fullTypeRegex = regexp.MustCompile("([a-zA-Z0-9]+)(\\[([0-9]*)?\\])?")
+	typeRegex     = regexp.MustCompile("([a-zA-Z]+)([0-9]*)?")
+)
+
 // NewType returns a fully parsed Type given by the input string or an error if it  can't be parsed.
 //
 // Strings can be in the format of:
@@ -61,51 +69,54 @@ type Type struct {
 //      address    int256    uint256    real[2]
 func NewType(t string) (typ Type, err error) {
 	// 1. full string 2. type 3. (opt.) is slice 4. (opt.) size
-	freg, err := regexp.Compile("([a-zA-Z0-9]+)(\\[([0-9]*)?\\])?")
-	if err != nil {
-		return Type{}, err
-	}
-	res := freg.FindAllStringSubmatch(t, -1)[0]
-	var (
-		isslice bool
-		size    int
-	)
+	// parse the full representation of the abi-type definition; including:
+	// * full string
+	// * type
+	// 	* is slice
+	//	* slice size
+	res := fullTypeRegex.FindAllStringSubmatch(t, -1)[0]
+
+	// check if type is slice and parse type.
 	switch {
 	case res[3] != "":
 		// err is ignored. Already checked for number through the regexp
-		size, _ = strconv.Atoi(res[3])
-		isslice = true
+		typ.SliceSize, _ = strconv.Atoi(res[3])
+		typ.IsSlice = true
 	case res[2] != "":
-		isslice = true
-		size = -1
+		typ.IsSlice, typ.SliceSize = true, -1
 	case res[0] == "":
-		return Type{}, fmt.Errorf("type parse error for `%s`", t)
+		return Type{}, fmt.Errorf("abi: type parse error: %s", t)
 	}
 
-	treg, err := regexp.Compile("([a-zA-Z]+)([0-9]*)?")
-	if err != nil {
-		return Type{}, err
+	// parse the type and size of the abi-type.
+	parsedType := typeRegex.FindAllStringSubmatch(res[1], -1)[0]
+	// varSize is the size of the variable
+	var varSize int
+	if len(parsedType[2]) > 0 {
+		var err error
+		varSize, err = strconv.Atoi(parsedType[2])
+		if err != nil {
+			return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err)
+		}
 	}
-
-	parsedType := treg.FindAllStringSubmatch(res[1], -1)[0]
-	vsize, _ := strconv.Atoi(parsedType[2])
-	vtype := parsedType[1]
-	// substitute canonical representation
-	if vsize == 0 && (vtype == "int" || vtype == "uint") {
-		vsize = 256
+	// varType is the parsed abi type
+	varType := parsedType[1]
+	// substitute canonical integer
+	if varSize == 0 && (varType == "int" || varType == "uint") {
+		varSize = 256
 		t += "256"
 	}
 
-	switch vtype {
+	switch varType {
 	case "int":
-		typ.Kind = reflect.Ptr
+		typ.Kind = reflect.Int
 		typ.Type = big_t
-		typ.Size = 256
+		typ.Size = varSize
 		typ.T = IntTy
 	case "uint":
-		typ.Kind = reflect.Ptr
+		typ.Kind = reflect.Uint
 		typ.Type = ubig_t
-		typ.Size = 256
+		typ.Size = varSize
 		typ.T = UintTy
 	case "bool":
 		typ.Kind = reflect.Bool
@@ -120,7 +131,7 @@ func NewType(t string) (typ Type, err error) {
 		typ.Kind = reflect.String
 		typ.Size = -1
 		typ.T = StringTy
-		if vsize > 0 {
+		if varSize > 0 {
 			typ.Size = 32
 		}
 	case "hash":
@@ -131,8 +142,8 @@ func NewType(t string) (typ Type, err error) {
 	case "bytes":
 		typ.Kind = reflect.Array
 		typ.Type = byte_ts
-		typ.Size = vsize
-		if vsize == 0 {
+		typ.Size = varSize
+		if varSize == 0 {
 			typ.T = BytesTy
 		} else {
 			typ.T = FixedBytesTy
@@ -140,13 +151,6 @@ func NewType(t string) (typ Type, err error) {
 	default:
 		return Type{}, fmt.Errorf("unsupported arg type: %s", t)
 	}
-
-	// if the type is a slice we must set Kind to a reflect.Slice
-	// so that serialisation can be determined based on this kind.
-	if isslice {
-		typ.Kind = reflect.Slice
-		typ.Size = size
-	}
 	typ.stringKind = t
 
 	return
@@ -173,14 +177,26 @@ func (t Type) pack(v interface{}) ([]byte, error) {
 	value := reflect.ValueOf(v)
 	switch kind := value.Kind(); kind {
 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		// check input is unsigned
 		if t.Type != ubig_t {
-			return nil, fmt.Errorf("type mismatch: %s for %T", t.Type, v)
+			return nil, fmt.Errorf("abi: type mismatch: %s for %T", t.Type, v)
+		}
+
+		// no implicit type casting
+		if int(value.Type().Size()*8) != t.Size {
+			return nil, fmt.Errorf("abi: cannot use type %T as type uint%d", v, t.Size)
 		}
+
 		return packNum(value, t.T), nil
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		if t.Type != ubig_t {
 			return nil, fmt.Errorf("type mismatch: %s for %T", t.Type, v)
 		}
+
+		// no implicit type casting
+		if int(value.Type().Size()*8) != t.Size {
+			return nil, fmt.Errorf("abi: cannot use type %T as type uint%d", v, t.Size)
+		}
 		return packNum(value, t.T), nil
 	case reflect.Ptr:
 		// If the value is a ptr do a assign check (only used by
@@ -201,7 +217,7 @@ func (t Type) pack(v interface{}) ([]byte, error) {
 			return packBytesSlice(value.Bytes(), value.Len()), nil
 		}
 
-		if t.Size > -1 && value.Len() > t.Size {
+		if t.SliceSize > -1 && value.Len() > t.SliceSize {
 			return nil, fmt.Errorf("%v out of bound. %d for %d", value.Kind(), value.Len(), t.Size)
 		}