diff --git a/rlp.go b/rlp.go
index 2c722cf7a25548beedb08c1f58166e74ba858ca6..cce839095575254ea7dbe1b9d71be85841355731 100644
--- a/rlp.go
+++ b/rlp.go
@@ -6,29 +6,51 @@ import (
   "math"
 )
 
-func EncodeSlice(slice []interface{}) []byte {
-  var buff bytes.Buffer
+func BinaryLength(n uint64) uint64 {
+  if n == 0 { return 0 }
 
-  for _, val := range slice {
-    switch t := val.(type) {
-    case []interface{}, []string:
-      buff.Write(Encode(t))
-    }
+  return 1 + BinaryLength(n / 256)
+}
+
+func ToBinarySlice(n uint64, length uint64) []uint64 {
+  if length == 0 {
+    length = BinaryLength(n)
   }
 
-  return buff.Bytes()
+  if n == 0 { return make([]uint64, 1) }
+
+  slice := ToBinarySlice(n / 256, 0)
+  slice = append(slice, n % 256)
+
+  return slice
+}
+
+func ToBin(n uint64, length uint64) string {
+  var buf bytes.Buffer
+  for _, val := range ToBinarySlice(n, length) {
+    buf.WriteString(string(val))
+  }
+
+  return buf.String()
+}
+
+func FromBin(data []byte) uint64 {
+  if len(data) == 0 { return 0 }
+
+  return FromBin(data[:len(data)-1]) * 256 + uint64(data[len(data)-1])
+}
+
+func Decode(data []byte, pos int) {
+  char := int(data[pos])
+  switch {
+  case char < 24:
+  }
 }
 
 func Encode(object interface{}) []byte {
   var buff bytes.Buffer
 
   switch t := object.(type) {
-  case string:
-    if len(t) < 56 {
-      buff.WriteString(string(len(t) + 64) + t)
-    } else {
-
-    }
   case uint32, uint64:
     var num uint64
     if _num, ok := t.(uint64); ok {
@@ -40,12 +62,49 @@ func Encode(object interface{}) []byte {
     if num >= 0 && num < 24 {
       buff.WriteString(string(num))
     } else if num <= uint64(math.Pow(2, 256)) {
+      b := ToBin(num, 0)
+      buff.WriteString(string(len(b) + 23) + b)
+    } else {
+      b := ToBin(num, 0)
+      b2 := ToBin(uint64(len(b)), 0)
+      buff.WriteString(string(len(b2) + 55) + b2 + b)
     }
+
+  case string:
+    if len(t) < 56 {
+      buff.WriteString(string(len(t) + 64) + t)
+    } else {
+      b2 := ToBin(uint64(len(t)), 0)
+      buff.WriteString(string(len(b2) + 119) + b2 + t)
+    }
+
   case []byte:
     // Cast the byte slice to a string
     buff.Write(Encode(string(t)))
-  case []interface{}:
-    buff.Write(EncodeSlice(t))
+
+  case []interface{}, []string:
+    // Inline function for writing the slice header
+    WriteSliceHeader := func(length int) {
+      if length < 56 {
+        buff.WriteString(string(length + 128))
+      } else {
+        b2 := ToBin(uint64(length), 0)
+        buff.WriteString(string(len(b2) + 183) + b2)
+      }
+    }
+
+    // FIXME How can I do this "better"?
+    if interSlice, ok := t.([]interface{}); ok {
+      WriteSliceHeader(len(interSlice))
+      for _, val := range interSlice {
+        buff.Write(Encode(val))
+      }
+    } else if stringSlice, ok := t.([]string); ok {
+      WriteSliceHeader(len(stringSlice))
+      for _, val := range stringSlice {
+        buff.Write(Encode(val))
+      }
+    }
   }
 
   return buff.Bytes()
diff --git a/rlp_test.go b/rlp_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..922b7097810a92c0072f613f7722eafe7be42aa7
--- /dev/null
+++ b/rlp_test.go
@@ -0,0 +1,20 @@
+package main
+
+import (
+  "testing"
+  "fmt"
+)
+
+func TestEncode(t *testing.T) {
+  strRes := "Cdog"
+  str := string(Encode("dog"))
+  if str != strRes {
+    t.Error(fmt.Sprintf("Expected %q, got %q", strRes, str))
+  }
+
+  sliceRes := "\u0083CdogCgodCcat"
+  slice := string(Encode([]string{"dog", "god", "cat"}))
+  if slice != sliceRes {
+    t.Error(fmt.Sprintf("Expected %q, got %q", sliceRes, slice))
+  }
+}