diff --git a/README.md b/README.md
index 6c7198f3a06688d79cfb5110c07360df387c37b6..2d4aeb6439d1994ab6d6ce3cb51ca757c64b55bd 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ mipsevm -- A MIPS runtime in the EVM (see also contracts/)
 
 ## TODO
 * Support fast generation of a specific state from the checkpoints
-** Load into Unicorn/evm from the trie
+  * Load into Unicorn/evm from the trie
 * Write binary search "responder"
 * Deploy to cheapETH!
 
diff --git a/mipsevm/trie.go b/mipsevm/trie.go
index 2e2635c287b6bad575629b9b69d94a97442af2ba..3e2ae4592e0d53215dcb6ebd48f54c729ddf57b5 100644
--- a/mipsevm/trie.go
+++ b/mipsevm/trie.go
@@ -29,6 +29,14 @@ func TrieToJson(root common.Hash, step int) []byte {
 	return b
 }
 
+func TrieFromJson(dat []byte) (common.Hash, int) {
+	var j Jtree
+	err := json.Unmarshal(dat, &j)
+	check(err)
+	Preimages = j.Preimages
+	return j.Root, j.Step
+}
+
 // TODO: this is copied from the oracle
 func (kw PreimageKeyValueWriter) Put(key []byte, value []byte) error {
 	hash := crypto.Keccak256Hash(value)
@@ -80,6 +88,12 @@ func ParseNode(node common.Hash, depth int, callback func(common.Hash) []byte) {
 	ParseNodeInternal(elems, depth, callback)
 }
 
+func RamFromTrie(root common.Hash) map[uint32](uint32) {
+	ram := make(map[uint32](uint32))
+	// TODO: write this
+	return ram
+}
+
 func RamToTrie(ram map[uint32](uint32)) common.Hash {
 	mt := trie.NewStackTrie(PreimageKeyValueWriter{})
 
diff --git a/mipsevm/trie_test.go b/mipsevm/trie_test.go
index 8cb9428606fb6d44c782ba4461b2c6fe4b897734..df328d1349bacf1097fb389e54740b9be985e502 100644
--- a/mipsevm/trie_test.go
+++ b/mipsevm/trie_test.go
@@ -3,6 +3,7 @@ package main
 import (
 	"fmt"
 	"io/ioutil"
+	"reflect"
 	"testing"
 
 	"github.com/ethereum/go-ethereum/common"
@@ -20,6 +21,21 @@ func TestTrie(t *testing.T) {
 	dat := TrieToJson(root, -1)
 	fmt.Println("serialized length is", len(dat))
 	ioutil.WriteFile("/tmp/cannon/ramtrie.json", dat, 0644)
+
+	// load the trie
+	oldPreLen := len(Preimages)
+	Preimages = make(map[common.Hash][]byte)
+	dat, err := ioutil.ReadFile("/tmp/cannon/ramtrie.json")
+	check(err)
+	newroot, _ := TrieFromJson(dat)
+	if root != newroot {
+		t.Fatal("loaded root mismatch")
+	}
+	if len(Preimages) != oldPreLen {
+		t.Fatal("preimage length mismatch")
+	}
+
+	// TODO: load memory when ready
 }
 
 func printRoot(ram map[uint32](uint32)) {
@@ -35,6 +51,19 @@ func printTrie(ram map[uint32](uint32)) {
 	})
 }
 
+func TestToFromTrie(t *testing.T) {
+	ram := make(map[uint32](uint32))
+	ram[0] = 1
+	ram[4] = 2
+
+	trie := RamToTrie(ram)
+	newram := RamFromTrie(trie)
+
+	if !reflect.DeepEqual(ram, newram) {
+		t.Fatal("ram to/from mismatch")
+	}
+}
+
 func TestBuggedTrie(t *testing.T) {
 	ram := make(map[uint32](uint32))
 
diff --git a/test/mips_test_memory.js b/test/mips_test_memory.js
index be3f19348a3ec8170ef831f5a70b36303134e636..a94f873e957c10b75601701e29d731ce2df76846 100644
--- a/test/mips_test_memory.js
+++ b/test/mips_test_memory.js
@@ -67,13 +67,20 @@ describe("MIPSMemory contract", function () {
     for (var i = 0; i < 100; i++) {
       const keys = Object.keys(kv)
       const choice = Math.random()
-      if (choice < 0.5 || keys.length == 0) {
+      if (choice < 0.3 || keys.length == 0) {
         // write new key
         const key = randint(0x100)*4
         const value = randint(0x100000000)
         console.log("writing", key, value)
         root = await write(mm, root, key, value)
         kv[key] = value
+      } else if (choice < 0.5) {
+        // write new high key
+        const key = randint(0x100)*4 + 0x10000000
+        const value = randint(0x100000000)
+        console.log("writing", key, value)
+        root = await write(mm, root, key, value)
+        kv[key] = value
       } else if (choice > 0.7) {
         // read old key
         const idx = randint(keys.length)