From c503a2b882a32ce70acd74d0ff1d46d195b3e88f Mon Sep 17 00:00:00 2001
From: Ezra Epstein <ezra_epstein@yahoo.com>
Date: Wed, 8 Nov 2017 21:10:25 -0800
Subject: [PATCH] Support for generating Java source from Truffle .json
 contract files.

---
 .../codegen/FunctionWrapperGenerator.java     |   69 +
 .../codegen/SolidityFunctionWrapper.java      |   53 +-
 .../SolidityFunctionWrapperGenerator.java     |   61 +-
 .../TruffleJsonFunctionWrapperGenerator.java  |  480 ++++++
 .../web3j/codegen/ContractJsonParseTest.java  |   68 +
 .../SolidityFunctionWrapperGeneratorTest.java |    1 -
 ...uffleJsonFunctionWrapperGeneratorTest.java |  101 ++
 .../resources/truffle/MetaCoin/ConvertLib.sol |    8 +
 .../resources/truffle/MetaCoin/MetaCoin.sol   |   34 +
 .../MetaCoin/build/contracts/ConvertLib.json  |  281 ++++
 .../MetaCoin/build/contracts/MetaCoin.json    | 1431 +++++++++++++++++
 .../main/java/org/web3j/console/Runner.java   |    4 +
 .../core/methods/response/AbiDefinition.java  |   40 +
 core/src/main/java/org/web3j/tx/Contract.java |   30 +
 .../main/java/org/web3j/utils/Strings.java    |    4 +
 15 files changed, 2612 insertions(+), 53 deletions(-)
 create mode 100644 codegen/src/main/java/org/web3j/codegen/FunctionWrapperGenerator.java
 create mode 100644 codegen/src/main/java/org/web3j/codegen/TruffleJsonFunctionWrapperGenerator.java
 create mode 100644 codegen/src/test/java/org/web3j/codegen/ContractJsonParseTest.java
 create mode 100644 codegen/src/test/java/org/web3j/codegen/TruffleJsonFunctionWrapperGeneratorTest.java
 create mode 100644 codegen/src/test/resources/truffle/MetaCoin/ConvertLib.sol
 create mode 100644 codegen/src/test/resources/truffle/MetaCoin/MetaCoin.sol
 create mode 100644 codegen/src/test/resources/truffle/MetaCoin/build/contracts/ConvertLib.json
 create mode 100644 codegen/src/test/resources/truffle/MetaCoin/build/contracts/MetaCoin.json

diff --git a/codegen/src/main/java/org/web3j/codegen/FunctionWrapperGenerator.java b/codegen/src/main/java/org/web3j/codegen/FunctionWrapperGenerator.java
new file mode 100644
index 000000000..4314f2e2a
--- /dev/null
+++ b/codegen/src/main/java/org/web3j/codegen/FunctionWrapperGenerator.java
@@ -0,0 +1,69 @@
+package org.web3j.codegen;
+
+import java.io.File;
+
+import static org.web3j.codegen.Console.exitError;
+
+/**
+ * Abstract base class for the concrete function wrapper generators.
+ */
+abstract class FunctionWrapperGenerator {
+
+    static final String JAVA_TYPES_ARG = "--javaTypes";
+    static final String SOLIDITY_TYPES_ARG = "--solidityTypes";
+
+    final File destinationDirLocation;
+    final String basePackageName;
+    final boolean useJavaNativeTypes;
+
+    FunctionWrapperGenerator(
+            String destinationDirLocation,
+            String basePackageName,
+            boolean useJavaNativeTypes) {
+
+        this.destinationDirLocation = new File(destinationDirLocation);
+        this.basePackageName = basePackageName;
+        this.useJavaNativeTypes = useJavaNativeTypes;
+    }
+
+    static boolean useJavaNativeTypes(String argVal, String usageString) {
+        boolean useJavaNativeTypes = true;
+        if (SOLIDITY_TYPES_ARG.equals(argVal)) {
+            useJavaNativeTypes = false;
+        } else if (JAVA_TYPES_ARG.equals(argVal)) {
+            useJavaNativeTypes = true;
+        } else {
+            exitError(usageString);
+        }
+        return useJavaNativeTypes;
+    }
+
+    static String parsePositionalArg(String[] args, int idx) {
+        if (args != null && args.length > idx) {
+            return args[idx];
+        } else {
+            return "";
+        }
+    }
+
+    static String parseParameterArgument(String[] args, String... parameters) {
+        for (String parameter : parameters) {
+            for (int i = 0; i < args.length; i++) {
+                if (args[i].equals(parameter)
+                        && i + 1 < args.length) {
+                    String parameterValue = args[i + 1];
+                    if (!parameterValue.startsWith("-")) {
+                        return parameterValue;
+                    }
+                }
+            }
+        }
+        return "";
+    }
+
+    static String getFileNameNoExtension(String fileName) {
+        String[] splitName = fileName.split("\\.(?=[^.]*$)");
+        return splitName[0];
+    }
+
+}
diff --git a/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java b/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java
index dd5ac96c8..1021ca6bb 100644
--- a/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java
+++ b/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java
@@ -5,7 +5,9 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.Callable;
 import javax.lang.model.element.Modifier;
 
@@ -81,10 +83,21 @@ public SolidityFunctionWrapper(boolean useNativeJavaTypes) {
         this.useNativeJavaTypes = useNativeJavaTypes;
     }
 
+    @SuppressWarnings("unchecked")
     public void generateJavaFiles(
             String contractName, String bin, String abi, String destinationDir,
             String basePackageName)
             throws IOException, ClassNotFoundException {
+        generateJavaFiles(contractName, bin,
+                loadContractDefinition(abi),
+                destinationDir, basePackageName,
+                null);
+    }
+
+    void generateJavaFiles(
+            String contractName, String bin, List<AbiDefinition> abi, String destinationDir,
+            String basePackageName, Map<String, String> addresses)
+            throws IOException, ClassNotFoundException {
         String className = Strings.capitaliseFirstLetter(contractName);
 
         TypeSpec.Builder classBuilder = createClassBuilder(className, bin);
@@ -92,13 +105,51 @@ public void generateJavaFiles(
         classBuilder.addMethod(buildConstructor(Credentials.class, CREDENTIALS));
         classBuilder.addMethod(buildConstructor(TransactionManager.class, TRANSACTION_MANAGER));
         classBuilder.addMethods(
-                buildFunctionDefinitions(className, classBuilder, loadContractDefinition(abi)));
+                buildFunctionDefinitions(className, classBuilder, abi));
         classBuilder.addMethod(buildLoad(className, Credentials.class, CREDENTIALS));
         classBuilder.addMethod(buildLoad(className, TransactionManager.class, TRANSACTION_MANAGER));
 
+        addAddressesSupport(classBuilder, addresses);
+
         write(basePackageName, classBuilder.build(), destinationDir);
     }
 
+    private void addAddressesSupport(TypeSpec.Builder classBuilder, Map<String, String> addresses) {
+        if (addresses != null) {
+
+            ClassName stringType = ClassName.get(String.class);
+            ClassName mapType = ClassName.get(HashMap.class);
+            TypeName mapStringString = ParameterizedTypeName.get(mapType, stringType, stringType);
+            FieldSpec addressesStaticField = FieldSpec
+                    .builder(mapStringString, "_addresses",
+                            Modifier.PROTECTED, Modifier.STATIC, Modifier.FINAL)
+                    .build();
+            classBuilder.addField(addressesStaticField);
+
+            final CodeBlock.Builder staticInit = CodeBlock.builder();
+            staticInit.addStatement("_addresses = new HashMap<>()");
+            addresses.forEach((k, v) ->
+                    staticInit.addStatement(String.format("_addresses.put(\"%1s\", \"%2s\")", k, v))
+            );
+            classBuilder.addStaticBlock(staticInit.build());
+
+            // See org.web3j.tx.Contract#getStaticDeployedAddress(String)
+            MethodSpec getAddress = MethodSpec
+                    .methodBuilder("getStaticDeployedAddress")
+                    .addModifiers(Modifier.PROTECTED)
+                    .returns(stringType)
+                    .addParameter(stringType, "networkId")
+                    .addCode(CodeBlock
+                    .builder()
+                    .addStatement("return _addresses.get(networkId)")
+                    .build())
+                    .build();
+            classBuilder.addMethod(getAddress);
+
+        }
+    }
+
+
     private TypeSpec.Builder createClassBuilder(String className, String binary) {
 
         String javadoc = CODEGEN_WARNING + getWeb3jVersion();
diff --git a/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapperGenerator.java b/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapperGenerator.java
index cd0ec1d95..7716578ec 100644
--- a/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapperGenerator.java
+++ b/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapperGenerator.java
@@ -18,7 +18,7 @@
 /**
  * Java wrapper source code generator for Solidity ABI format.
  */
-public class SolidityFunctionWrapperGenerator {
+public class SolidityFunctionWrapperGenerator extends FunctionWrapperGenerator {
 
     private static final String USAGE = "solidity generate "
             + "[--javaTypes|--solidityTypes] "
@@ -26,14 +26,8 @@ public class SolidityFunctionWrapperGenerator {
             + "-p|--package <base package name> "
             + "-o|--output <destination base directory>";
 
-    static final String JAVA_TYPES_ARG = "--javaTypes";
-    static final String SOLIDITY_TYPES_ARG = "--solidityTypes";
-
-    private String binaryFileLocation;
-    private String absFileLocation;
-    private File destinationDirLocation;
-    private String basePackageName;
-    private boolean useJavaNativeTypes;
+    private final String binaryFileLocation;
+    private final String absFileLocation;
 
     private SolidityFunctionWrapperGenerator(
             String binaryFileLocation,
@@ -42,11 +36,9 @@ private SolidityFunctionWrapperGenerator(
             String basePackageName,
             boolean useJavaNativeTypes) {
 
+        super(destinationDirLocation, basePackageName, useJavaNativeTypes);
         this.binaryFileLocation = binaryFileLocation;
         this.absFileLocation = absFileLocation;
-        this.destinationDirLocation = new File(destinationDirLocation);
-        this.basePackageName = basePackageName;
-        this.useJavaNativeTypes = useJavaNativeTypes;
     }
 
     public static void run(String[] args) throws Exception {
@@ -72,14 +64,7 @@ public static void main(String[] args) throws Exception {
             exitError(USAGE);
         }
 
-        boolean useJavaNativeTypes = true;
-        if (fullArgs[0].equals(SOLIDITY_TYPES_ARG)) {
-            useJavaNativeTypes = false;
-        } else if (fullArgs[0].equals(JAVA_TYPES_ARG)) {
-            useJavaNativeTypes = true;
-        } else {
-            exitError(USAGE);
-        }
+        boolean useJavaNativeTypes = useJavaNativeTypes(fullArgs[0], USAGE);
 
         String binaryFileLocation = parsePositionalArg(fullArgs, 1);
         String absFileLocation = parsePositionalArg(fullArgs, 2);
@@ -102,27 +87,11 @@ public static void main(String[] args) throws Exception {
                 .generate();
     }
 
-    private static String parsePositionalArg(String[] args, int idx) {
-        if (args != null && args.length > idx) {
-            return args[idx];
-        } else {
-            return "";
-        }
-    }
-
-    private static String parseParameterArgument(String[] args, String... parameters) {
-        for (String parameter : parameters) {
-            for (int i = 0; i < args.length; i++) {
-                if (args[i].equals(parameter)
-                        && i + 1 < args.length) {
-                    String parameterValue = args[i + 1];
-                    if (!parameterValue.startsWith("-")) {
-                        return parameterValue;
-                    }
-                }
-            }
-        }
-        return "";
+    static List<AbiDefinition> loadContractDefinition(File absFile)
+            throws IOException {
+        ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper();
+        AbiDefinition[] abiDefinition = objectMapper.readValue(absFile, AbiDefinition[].class);
+        return Arrays.asList(abiDefinition);
     }
 
     private void generate() throws IOException, ClassNotFoundException {
@@ -157,15 +126,5 @@ private void generate() throws IOException, ClassNotFoundException {
         }
     }
 
-    private static List<AbiDefinition> loadContractDefinition(File absFile)
-            throws IOException {
-        ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper();
-        AbiDefinition[] abiDefinition = objectMapper.readValue(absFile, AbiDefinition[].class);
-        return Arrays.asList(abiDefinition);
-    }
 
-    static String getFileNameNoExtension(String fileName) {
-        String[] splitName = fileName.split("\\.(?=[^.]*$)");
-        return splitName[0];
-    }
 }
\ No newline at end of file
diff --git a/codegen/src/main/java/org/web3j/codegen/TruffleJsonFunctionWrapperGenerator.java b/codegen/src/main/java/org/web3j/codegen/TruffleJsonFunctionWrapperGenerator.java
new file mode 100644
index 000000000..bbeba6d83
--- /dev/null
+++ b/codegen/src/main/java/org/web3j/codegen/TruffleJsonFunctionWrapperGenerator.java
@@ -0,0 +1,480 @@
+package org.web3j.codegen;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.web3j.protocol.ObjectMapperFactory;
+import org.web3j.protocol.core.methods.response.AbiDefinition;
+import org.web3j.utils.Strings;
+
+import static org.web3j.codegen.Console.exitError;
+import static org.web3j.utils.Collection.tail;
+
+/**
+ * Java wrapper source code generator for Truffle JSON format. Truffle embeds the Solidity ABI
+ * formatted JSON in its own format. That format also gives access to the binary code. It also
+ * contains information about deployment addresses. This should make integration with Truffle
+ * easier.
+ */
+public class TruffleJsonFunctionWrapperGenerator extends FunctionWrapperGenerator {
+
+    private static final String USAGE = "truffle generate "
+            + "[--javaTypes|--solidityTypes] "
+            + "<input truffle json file>.json "
+            + "-p|--package <base package name> "
+            + "-o|--output <destination base directory>";
+
+
+    private String jsonFileLocation;
+
+    private TruffleJsonFunctionWrapperGenerator(
+            String jsonFileLocation,
+            String destinationDirLocation,
+            String basePackageName,
+            boolean useJavaNativeTypes) {
+
+        super(destinationDirLocation, basePackageName, useJavaNativeTypes);
+        this.jsonFileLocation = jsonFileLocation;
+    }
+
+    public static void run(String[] args) throws Exception {
+        if (args.length < 1 || !"generate".equals(args[0])) {
+            exitError(USAGE);
+        } else {
+            main(tail(args));
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        String[] fullArgs;
+        if (args.length == 5) {
+            fullArgs = new String[args.length + 1];
+            fullArgs[0] = JAVA_TYPES_ARG;
+            System.arraycopy(args, 0, fullArgs, 1, args.length);
+        } else {
+            fullArgs = args;
+        }
+
+        if (fullArgs.length != 6) {
+            exitError(USAGE);
+        }
+
+        boolean useJavaNativeTypes = useJavaNativeTypes(fullArgs[0], USAGE);
+
+        String jsonFileLocation = parsePositionalArg(fullArgs, 1);
+        String destinationDirLocation = parseParameterArgument(fullArgs, "-o", "--outputDir");
+        String basePackageName = parseParameterArgument(fullArgs, "-p", "--package");
+
+        if (Strings.isEmpty(jsonFileLocation)
+                || Strings.isEmpty(destinationDirLocation)
+                || Strings.isEmpty(basePackageName)) {
+            exitError(USAGE);
+        }
+
+        new TruffleJsonFunctionWrapperGenerator(
+                jsonFileLocation,
+                destinationDirLocation,
+                basePackageName,
+                useJavaNativeTypes)
+                .generate();
+    }
+
+    static Contract loadContractDefinition(File jsonFile)
+            throws IOException {
+        ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper();
+        return objectMapper.readValue(jsonFile, Contract.class);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void generate() throws IOException, ClassNotFoundException {
+
+        File truffleJsonFile = new File(jsonFileLocation);
+        if (!truffleJsonFile.exists() || !truffleJsonFile.canRead()) {
+            exitError("Invalid input json file specified: " + jsonFileLocation);
+        }
+
+        String fileName = truffleJsonFile.getName();
+        String contractName = getFileNameNoExtension(fileName);
+
+        Contract c = loadContractDefinition(truffleJsonFile);
+        if (c == null) {
+            exitError("Unable to parse input json file");
+        } else {
+            String className = Strings.capitaliseFirstLetter(contractName);
+            System.out.printf("Generating " + basePackageName + "." + className + " ... ");
+            Map<String, String> addresses;
+            if (c.networks != null && !c.networks.isEmpty()) {
+                addresses = c.networks.entrySet().stream().collect(Collectors.toMap(
+                        Map.Entry::getKey, e -> e.getValue().getAddress()
+                ));
+            } else {
+                addresses = Collections.EMPTY_MAP;
+            }
+            new SolidityFunctionWrapper(useJavaNativeTypes)
+                    .generateJavaFiles(contractName,
+                            c.bytecode,
+                            c.abi,
+                            destinationDirLocation.toString(),
+                            basePackageName,
+                            addresses);
+            System.out.println("File written to " + destinationDirLocation.toString() + "\n");
+        }
+    }
+
+    /**
+     * Truffle Contract <p> Describes a contract exported by and consumable by Truffle, which may
+     * include information about deployed instances on networks. </p>
+     */
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    @JsonPropertyOrder({
+            "contractName",
+            "abi",
+            "bytecode",
+            "deployedBytecode",
+            "sourceMap",
+            "deployedSourceMap",
+            "source",
+            "sourcePath",
+            "ast",
+            "compiler",
+            "networks",
+            "schemaVersion",
+            "updatedAt"
+    })
+    public static class Contract {
+
+        @JsonProperty("contractName")
+        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "^[a-zA-Z_][a-zA-Z0-9_]*$")
+        public String contractName;
+        @JsonProperty(value = "abi", required = true)
+        public List<AbiDefinition> abi;
+        @JsonProperty("bytecode")
+        @JsonFormat(shape = JsonFormat.Shape.STRING,
+                pattern = "^0x0$|^0x([a-fA-F0-9]{2}|__.{38})+$")
+        public String bytecode;
+        @JsonProperty("deployedBytecode")
+        @JsonFormat(shape = JsonFormat.Shape.STRING,
+                pattern = "^0x0$|^0x([a-fA-F0-9]{2}|__.{38})+$")
+        public String deployedBytecode;
+        @JsonProperty("sourceMap")
+        public String sourceMap;
+        @JsonProperty("deployedSourceMap")
+        public String deployedSourceMap;
+        @JsonProperty("source")
+        public String source;
+        @JsonProperty("sourcePath")
+        public String sourcePath;
+        @JsonProperty("ast")
+        public JsonNode ast;
+        @JsonProperty("compiler")
+        public Compiler compiler;
+        @JsonProperty("networks")
+        public Map<String, NetworkInfo> networks;
+        @JsonProperty("schemaVersion")
+        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "[0-9]+\\.[0-9]+\\.[0-9]+")
+        public String schemaVersion;
+        @JsonProperty("updatedAt")
+        @JsonFormat(shape = JsonFormat.Shape.STRING,
+                pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "GMT")
+        public Date updatedAt;
+
+        /**
+         * No args constructor for use in serialization.
+         */
+        public Contract() {
+        }
+
+        /**
+         * Default constructor.
+         */
+        public Contract(String contractName, List<AbiDefinition> abi, String bytecode,
+                String deployedBytecode,
+                String sourceMap, String deployedSourceMap, String source, String sourcePath,
+                JsonNode ast,
+                Compiler compiler, Map<String, NetworkInfo> networks, String schemaVersion,
+                Date updatedAt) {
+            super();
+            this.contractName = contractName;
+            this.abi = abi;
+            this.bytecode = bytecode;
+            this.deployedBytecode = deployedBytecode;
+            this.sourceMap = sourceMap;
+            this.deployedSourceMap = deployedSourceMap;
+            this.source = source;
+            this.sourcePath = sourcePath;
+            this.ast = ast;
+            this.compiler = compiler;
+            this.networks = networks;
+            this.schemaVersion = schemaVersion;
+            this.updatedAt = updatedAt;
+        }
+
+        public Contract withContractName(String contractName) {
+            this.contractName = contractName;
+            return this;
+        }
+
+        public Contract withAbi(List<AbiDefinition> abi) {
+            this.abi = abi;
+            return this;
+        }
+
+        public Contract withBytecode(String bytecode) {
+            this.bytecode = bytecode;
+            return this;
+        }
+
+        public Contract withDeployedBytecode(String deployedBytecode) {
+            this.deployedBytecode = deployedBytecode;
+            return this;
+        }
+
+        public Contract withSourceMap(String sourceMap) {
+            this.sourceMap = sourceMap;
+            return this;
+        }
+
+        public Contract withDeployedSourceMap(String deployedSourceMap) {
+            this.deployedSourceMap = deployedSourceMap;
+            return this;
+        }
+
+        public Contract withSource(String source) {
+            this.source = source;
+            return this;
+        }
+
+        public Contract withSourcePath(String sourcePath) {
+            this.sourcePath = sourcePath;
+            return this;
+        }
+
+        public Contract withAst(JsonNode ast) {
+            this.ast = ast;
+            return this;
+        }
+
+        public Contract withCompiler(Compiler compiler) {
+            this.compiler = compiler;
+            return this;
+        }
+
+        public Contract withNetworks(Map<String, NetworkInfo> networks) {
+            this.networks = networks;
+            return this;
+        }
+
+        public Contract withSchemaVersion(String schemaVersion) {
+            this.schemaVersion = schemaVersion;
+            return this;
+        }
+
+        public Contract withUpdatedAt(Date updatedAt) {
+            this.updatedAt = updatedAt;
+            return this;
+        }
+
+        public String getContractName() {
+            return contractName;
+        }
+
+        public List<AbiDefinition> getAbi() {
+            return abi;
+        }
+
+        public String getBytecode() {
+            return bytecode;
+        }
+
+        public String getDeployedBytecode() {
+            return deployedBytecode;
+        }
+
+        public String getSourceMap() {
+            return sourceMap;
+        }
+
+        public String getDeployedSourceMap() {
+            return deployedSourceMap;
+        }
+
+        public String getSource() {
+            return source;
+        }
+
+        public String getSourcePath() {
+            return sourcePath;
+        }
+
+        public JsonNode getAst() {
+            return ast;
+        }
+
+        public Compiler getCompiler() {
+            return compiler;
+        }
+
+        public Map<String, NetworkInfo> getNetworks() {
+            return networks;
+        }
+
+        public String getSchemaVersion() {
+            return schemaVersion;
+        }
+
+        public Date getUpdatedAt() {
+            return updatedAt;
+        }
+
+        public NetworkInfo getNetwork(String networkId) {
+            return networks.get(networkId);
+        }
+
+        public String getAddress(String networkId) {
+            NetworkInfo network = getNetwork(networkId);
+            return network == null ? null : network.getAddress();
+        }
+
+        /**
+         * Convenience method to get the deployed address of the contract.
+         *
+         * @param network the contract's address on this Ethereum network
+         * @return the contract's address or <code>null</code> if there isn't one known.
+         */
+        public String getAddress(Network network) {
+            return getAddress(Long.toString(network.id));
+        }
+
+        enum Network {
+            olympic(0), mainnet(1), morden(2), ropsten(3), rinkeby(4), kovan(42);
+
+            public final long id;
+
+            Network(long id) {
+                this.id = id;
+            }
+        }
+
+    }
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    @JsonPropertyOrder({
+            "name",
+            "version"
+    })
+    public static class Compiler {
+
+        @JsonProperty("name")
+        public String name;
+        @JsonProperty("version")
+        public String version;
+        @JsonIgnore
+        private Map<String, JsonNode> additionalProperties = new HashMap<String, JsonNode>();
+
+        /**
+         * No args constructor for use in serialization.
+         */
+        public Compiler() {
+        }
+
+        /**
+         * Default constructor.
+         */
+        public Compiler(String name, String version) {
+            super();
+            this.name = name;
+            this.version = version;
+        }
+
+        public Compiler withName(String name) {
+            this.name = name;
+            return this;
+        }
+
+        public Compiler withVersion(String version) {
+            this.version = version;
+            return this;
+        }
+
+        @JsonAnyGetter
+        public Map<String, JsonNode> getAdditionalProperties() {
+            return this.additionalProperties;
+        }
+
+        @JsonAnySetter
+        public void setAdditionalProperty(String name, JsonNode value) {
+            this.additionalProperties.put(name, value);
+        }
+
+        public Compiler withAdditionalProperty(String name, JsonNode value) {
+            this.additionalProperties.put(name, value);
+            return this;
+        }
+
+    }
+
+
+    // For now we just ignore "events"
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    @JsonPropertyOrder({
+            "events",
+            "links",
+            "address"
+    })
+    public static class NetworkInfo {
+
+        @JsonProperty("events")
+        public Map<String, JsonNode> events;
+        @JsonProperty("links")
+        public Map<String, JsonNode> links;
+        @JsonProperty("address")
+        public String address;
+
+        /**
+         * No args constructor for use in serialization.
+         */
+        public NetworkInfo() {
+        }
+
+        public NetworkInfo(Map<String, JsonNode> events, Map<String, JsonNode> links,
+                String address) {
+            super();
+            this.events = events;
+            this.links = links;
+            this.address = address;
+        }
+
+        public NetworkInfo withAddress(String address) {
+            this.address = address;
+            return this;
+        }
+
+        public String getAddress() {
+            return address;
+        }
+
+        public void setAddress(String address) {
+            this.address = address;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/codegen/src/test/java/org/web3j/codegen/ContractJsonParseTest.java b/codegen/src/test/java/org/web3j/codegen/ContractJsonParseTest.java
new file mode 100644
index 000000000..e345c7849
--- /dev/null
+++ b/codegen/src/test/java/org/web3j/codegen/ContractJsonParseTest.java
@@ -0,0 +1,68 @@
+package org.web3j.codegen;
+
+import java.io.File;
+import java.net.URL;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.web3j.protocol.core.methods.response.AbiDefinition;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.web3j.codegen.TruffleJsonFunctionWrapperGenerator.Contract;
+import static org.web3j.codegen.TruffleJsonFunctionWrapperGenerator.loadContractDefinition;
+
+/**
+ * Test that we can parse Truffle Contract from JSON file.
+ */
+public class ContractJsonParseTest {
+
+    static final String BUILD_CONTRACTS = "build" + File.separator + "contracts";
+    private String contractBaseDir;
+
+    static String jsonFileLocation(String baseDir,
+            String contractName, String inputFileName) {
+        return baseDir + File.separator + contractName + File.separator + BUILD_CONTRACTS
+                + File.separator + inputFileName + ".json";
+    }
+
+    @SuppressWarnings("SameParameterValue")
+    static Contract parseContractJson(String baseDir,
+            String contractName, String inputFileName)
+            throws Exception {
+
+        String fileLocation = jsonFileLocation(baseDir, contractName, inputFileName);
+        return loadContractDefinition(new File(fileLocation));
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        URL url = SolidityFunctionWrapperGeneratorTest.class.getClass().getResource("/truffle");
+        contractBaseDir = url.getPath();
+    }
+
+    @Test
+    public void testParseMetaCoin() throws Exception {
+        Contract mc = parseContractJson(contractBaseDir, "MetaCoin", "MetaCoin");
+
+        assertEquals("Unexpected contract name", "MetaCoin", mc.getContractName());
+    }
+
+    @Test
+    public void testParseConvertLib() throws Exception {
+        Contract mc = parseContractJson(contractBaseDir, "MetaCoin", "ConvertLib");
+
+        assertEquals("Unexpected contract name", "ConvertLib", mc.getContractName());
+        assertEquals("Unexpected number of functions", 1, mc.abi.size());
+        AbiDefinition abi = mc.abi.get(0);
+        assertEquals("Unexpected function name", "convert", abi.getName());
+        assertTrue("Expected function to be 'constant'", abi.isConstant());
+        assertFalse("Expected function to not be 'payable'", abi.isPayable());
+        assertEquals("Expected abi to represent a function", "function", abi.getType());
+        assertEquals("Expected the 'pure' for the state mutability setting", "pure",
+                abi.getStateMutability());
+
+    }
+}
\ No newline at end of file
diff --git a/codegen/src/test/java/org/web3j/codegen/SolidityFunctionWrapperGeneratorTest.java b/codegen/src/test/java/org/web3j/codegen/SolidityFunctionWrapperGeneratorTest.java
index d899c903c..966a192ea 100644
--- a/codegen/src/test/java/org/web3j/codegen/SolidityFunctionWrapperGeneratorTest.java
+++ b/codegen/src/test/java/org/web3j/codegen/SolidityFunctionWrapperGeneratorTest.java
@@ -4,7 +4,6 @@
 import java.io.IOException;
 import java.net.URL;
 import java.util.Arrays;
-import java.util.Collections;
 import javax.tools.DiagnosticCollector;
 import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
diff --git a/codegen/src/test/java/org/web3j/codegen/TruffleJsonFunctionWrapperGeneratorTest.java b/codegen/src/test/java/org/web3j/codegen/TruffleJsonFunctionWrapperGeneratorTest.java
new file mode 100644
index 000000000..008d36dd6
--- /dev/null
+++ b/codegen/src/test/java/org/web3j/codegen/TruffleJsonFunctionWrapperGeneratorTest.java
@@ -0,0 +1,101 @@
+package org.web3j.codegen;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.web3j.TempFileProvider;
+import org.web3j.utils.Strings;
+
+import static org.junit.Assert.assertTrue;
+import static org.web3j.codegen.FunctionWrapperGenerator.JAVA_TYPES_ARG;
+import static org.web3j.codegen.FunctionWrapperGenerator.SOLIDITY_TYPES_ARG;
+
+public class TruffleJsonFunctionWrapperGeneratorTest extends TempFileProvider {
+
+    private static final String PackageName = "org.web3j.unittests.truffle.java";
+
+    private String contractBaseDir;
+
+    private static void verifyGeneratedCode(String sourceFile) throws IOException {
+        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
+
+        try (StandardJavaFileManager fileManager =
+                compiler.getStandardFileManager(diagnostics, null, null)) {
+            Iterable<? extends JavaFileObject> compilationUnits = fileManager
+                    .getJavaFileObjectsFromStrings(Collections.singletonList(sourceFile));
+            JavaCompiler.CompilationTask task = compiler.getTask(
+                    null, fileManager, diagnostics, null, null, compilationUnits);
+            assertTrue("Generated contract contains compile time error", task.call());
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        URL url = SolidityFunctionWrapperGeneratorTest.class.getClass().getResource("/truffle");
+        contractBaseDir = url.getPath();
+    }
+
+    @Test
+    public void testLibGeneration() throws Exception {
+        testCodeGenerationJvmTypes("MetaCoin", "ConvertLib");
+        testCodeGenerationSolidtyTypes("MetaCoin", "ConvertLib");
+    }
+
+    @Test
+    public void testContractGeneration() throws Exception {
+        testCodeGenerationJvmTypes("MetaCoin", "MetaCoin");
+        testCodeGenerationSolidtyTypes("MetaCoin", "MetaCoin");
+    }
+
+    @SuppressWarnings("SameParameterValue")
+    private void testCodeGenerationJvmTypes(
+            String contractName, String inputFileName) throws Exception {
+
+        testCodeGeneration(
+                contractName, inputFileName, PackageName, JAVA_TYPES_ARG);
+
+    }
+
+    @SuppressWarnings("SameParameterValue")
+    private void testCodeGenerationSolidtyTypes(
+            String contractName, String inputFileName) throws Exception {
+
+        testCodeGeneration(
+                contractName, inputFileName, PackageName, SOLIDITY_TYPES_ARG);
+
+    }
+
+    private void testCodeGeneration(
+            String contractName, String inputFileName, String packageName, String types)
+            throws Exception {
+
+        TruffleJsonFunctionWrapperGenerator.main(Arrays.asList(
+                types,
+                ContractJsonParseTest
+                        .jsonFileLocation(contractBaseDir, contractName, inputFileName),
+                "-p", packageName,
+                "-o", tempDirPath
+        ).toArray(new String[0]));
+
+        verifyGeneratedCode(tempDirPath + File.separator
+                + packageName.replace('.', File.separatorChar) + File.separator
+                + Strings.capitaliseFirstLetter(inputFileName) + ".java");
+    }
+
+
+}
\ No newline at end of file
diff --git a/codegen/src/test/resources/truffle/MetaCoin/ConvertLib.sol b/codegen/src/test/resources/truffle/MetaCoin/ConvertLib.sol
new file mode 100644
index 000000000..99f004dfe
--- /dev/null
+++ b/codegen/src/test/resources/truffle/MetaCoin/ConvertLib.sol
@@ -0,0 +1,8 @@
+pragma solidity ^0.4.2;
+
+library ConvertLib{
+	function convert(uint amount,uint conversionRate) pure public returns (uint convertedAmount)
+	{
+		return amount * conversionRate;
+	}
+}
diff --git a/codegen/src/test/resources/truffle/MetaCoin/MetaCoin.sol b/codegen/src/test/resources/truffle/MetaCoin/MetaCoin.sol
new file mode 100644
index 000000000..2658d0466
--- /dev/null
+++ b/codegen/src/test/resources/truffle/MetaCoin/MetaCoin.sol
@@ -0,0 +1,34 @@
+pragma solidity ^0.4.2;
+
+import "./ConvertLib.sol";
+
+// This is just a simple example of a coin-like contract.
+// It is not standards compatible and cannot be expected to talk to other
+// coin/token contracts. If you want to create a standards-compliant
+// token, see: https://github.com/ConsenSys/Tokens. Cheers!
+
+contract MetaCoin {
+	mapping (address => uint) balances;
+
+	event Transfer(address indexed _from, address indexed _to, uint256 _value);
+
+	function MetaCoin() public {
+		balances[tx.origin] = 10000;
+	}
+
+	function sendCoin(address receiver, uint amount) public returns(bool sufficient) {
+		if (balances[msg.sender] < amount) return false;
+		balances[msg.sender] -= amount;
+		balances[receiver] += amount;
+		Transfer(msg.sender, receiver, amount);
+		return true;
+	}
+
+	function getBalanceInEth(address addr) view public returns(uint){
+		return ConvertLib.convert(getBalance(addr),2);
+	}
+
+	function getBalance(address addr) view public returns(uint) {
+		return balances[addr];
+	}
+}
diff --git a/codegen/src/test/resources/truffle/MetaCoin/build/contracts/ConvertLib.json b/codegen/src/test/resources/truffle/MetaCoin/build/contracts/ConvertLib.json
new file mode 100644
index 000000000..a54254200
--- /dev/null
+++ b/codegen/src/test/resources/truffle/MetaCoin/build/contracts/ConvertLib.json
@@ -0,0 +1,281 @@
+{
+  "contractName": "ConvertLib",
+  "abi": [
+    {
+      "constant": true,
+      "inputs": [
+        {
+          "name": "amount",
+          "type": "uint256"
+        },
+        {
+          "name": "conversionRate",
+          "type": "uint256"
+        }
+      ],
+      "name": "convert",
+      "outputs": [
+        {
+          "name": "convertedAmount",
+          "type": "uint256"
+        }
+      ],
+      "payable": false,
+      "stateMutability": "pure",
+      "type": "function"
+    }
+  ],
+  "bytecode": "0x6060604052341561000f57600080fd5b60b08061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806396e4ee3d146044575b600080fd5b606160048080359060200190919080359060200190919050506077565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820fc2416f7929b800f6d4af1a1e6d2a8d7d8ac81998f8c072a99314c7bf5c2a5f80029",
+  "deployedBytecode": "0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806396e4ee3d146044575b600080fd5b606160048080359060200190919080359060200190919050506077565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820fc2416f7929b800f6d4af1a1e6d2a8d7d8ac81998f8c072a99314c7bf5c2a5f80029",
+  "sourceMap": "25:155:0:-;;;;;;;;;;;;;;;;;",
+  "deployedSourceMap": "25:155:0:-;;;;;;;;;;;;;;;;;;;;;;;;46:132;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;117:20;160:14;151:6;:23;144:30;;46:132;;;;:::o",
+  "source": "pragma solidity ^0.4.2;\n\nlibrary ConvertLib{\n\tfunction convert(uint amount,uint conversionRate) pure public returns (uint convertedAmount)\n\t{\n\t\treturn amount * conversionRate;\n\t}\n}\n",
+  "sourcePath": "/Users/ezra/Developer/blockchain/truffle_webpack/contracts/ConvertLib.sol",
+  "ast": {
+    "attributes": {
+      "absolutePath": "/Users/ezra/Developer/blockchain/truffle_webpack/contracts/ConvertLib.sol",
+      "exportedSymbols": {
+        "ConvertLib": [
+          16
+        ]
+      }
+    },
+    "children": [
+      {
+        "attributes": {
+          "literals": [
+            "solidity",
+            "^",
+            "0.4",
+            ".2"
+          ]
+        },
+        "id": 1,
+        "name": "PragmaDirective",
+        "src": "0:23:0"
+      },
+      {
+        "attributes": {
+          "baseContracts": [
+            null
+          ],
+          "contractDependencies": [
+            null
+          ],
+          "contractKind": "library",
+          "documentation": null,
+          "fullyImplemented": true,
+          "linearizedBaseContracts": [
+            16
+          ],
+          "name": "ConvertLib",
+          "scope": 17
+        },
+        "children": [
+          {
+            "attributes": {
+              "constant": true,
+              "implemented": true,
+              "isConstructor": false,
+              "modifiers": [
+                null
+              ],
+              "name": "convert",
+              "payable": false,
+              "scope": 16,
+              "stateMutability": "pure",
+              "superFunction": null,
+              "visibility": "public"
+            },
+            "children": [
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "name": "amount",
+                      "scope": 15,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "uint256",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "uint",
+                          "type": "uint256"
+                        },
+                        "id": 2,
+                        "name": "ElementaryTypeName",
+                        "src": "63:4:0"
+                      }
+                    ],
+                    "id": 3,
+                    "name": "VariableDeclaration",
+                    "src": "63:11:0"
+                  },
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "name": "conversionRate",
+                      "scope": 15,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "uint256",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "uint",
+                          "type": "uint256"
+                        },
+                        "id": 4,
+                        "name": "ElementaryTypeName",
+                        "src": "75:4:0"
+                      }
+                    ],
+                    "id": 5,
+                    "name": "VariableDeclaration",
+                    "src": "75:19:0"
+                  }
+                ],
+                "id": 6,
+                "name": "ParameterList",
+                "src": "62:33:0"
+              },
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "name": "convertedAmount",
+                      "scope": 15,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "uint256",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "uint",
+                          "type": "uint256"
+                        },
+                        "id": 7,
+                        "name": "ElementaryTypeName",
+                        "src": "117:4:0"
+                      }
+                    ],
+                    "id": 8,
+                    "name": "VariableDeclaration",
+                    "src": "117:20:0"
+                  }
+                ],
+                "id": 9,
+                "name": "ParameterList",
+                "src": "116:22:0"
+              },
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "functionReturnParameters": 9
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "argumentTypes": null,
+                          "commonType": {
+                            "typeIdentifier": "t_uint256",
+                            "typeString": "uint256"
+                          },
+                          "isConstant": false,
+                          "isLValue": false,
+                          "isPure": false,
+                          "lValueRequested": false,
+                          "operator": "*",
+                          "type": "uint256"
+                        },
+                        "children": [
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "overloadedDeclarations": [
+                                null
+                              ],
+                              "referencedDeclaration": 3,
+                              "type": "uint256",
+                              "value": "amount"
+                            },
+                            "id": 10,
+                            "name": "Identifier",
+                            "src": "151:6:0"
+                          },
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "overloadedDeclarations": [
+                                null
+                              ],
+                              "referencedDeclaration": 5,
+                              "type": "uint256",
+                              "value": "conversionRate"
+                            },
+                            "id": 11,
+                            "name": "Identifier",
+                            "src": "160:14:0"
+                          }
+                        ],
+                        "id": 12,
+                        "name": "BinaryOperation",
+                        "src": "151:23:0"
+                      }
+                    ],
+                    "id": 13,
+                    "name": "Return",
+                    "src": "144:30:0"
+                  }
+                ],
+                "id": 14,
+                "name": "Block",
+                "src": "140:38:0"
+              }
+            ],
+            "id": 15,
+            "name": "FunctionDefinition",
+            "src": "46:132:0"
+          }
+        ],
+        "id": 16,
+        "name": "ContractDefinition",
+        "src": "25:155:0"
+      }
+    ],
+    "id": 17,
+    "name": "SourceUnit",
+    "src": "0:181:0"
+  },
+  "compiler": {
+    "name": "solc",
+    "version": "0.4.18+commit.9cf6e910.Emscripten.clang"
+  },
+  "networks": {
+    "4": {
+      "events": {},
+      "links": {},
+      "address": "0x14d00a701a2f0d4d65eebaf191f4f60bbaa1da36"
+    },
+    "4447": {
+      "events": {},
+      "links": {},
+      "address": "0xcfeb869f69431e42cdb54a4f4f105c19c080a601"
+    }
+  },
+  "schemaVersion": "1.0.1",
+  "updatedAt": "2017-11-07T20:44:02.301Z"
+}
\ No newline at end of file
diff --git a/codegen/src/test/resources/truffle/MetaCoin/build/contracts/MetaCoin.json b/codegen/src/test/resources/truffle/MetaCoin/build/contracts/MetaCoin.json
new file mode 100644
index 000000000..8bed99e71
--- /dev/null
+++ b/codegen/src/test/resources/truffle/MetaCoin/build/contracts/MetaCoin.json
@@ -0,0 +1,1431 @@
+{
+  "contractName": "MetaCoin",
+  "abi": [
+    {
+      "constant": true,
+      "inputs": [
+        {
+          "name": "addr",
+          "type": "address"
+        }
+      ],
+      "name": "getBalanceInEth",
+      "outputs": [
+        {
+          "name": "",
+          "type": "uint256"
+        }
+      ],
+      "payable": false,
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "constant": false,
+      "inputs": [
+        {
+          "name": "receiver",
+          "type": "address"
+        },
+        {
+          "name": "amount",
+          "type": "uint256"
+        }
+      ],
+      "name": "sendCoin",
+      "outputs": [
+        {
+          "name": "sufficient",
+          "type": "bool"
+        }
+      ],
+      "payable": false,
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "constant": true,
+      "inputs": [
+        {
+          "name": "addr",
+          "type": "address"
+        }
+      ],
+      "name": "getBalance",
+      "outputs": [
+        {
+          "name": "",
+          "type": "uint256"
+        }
+      ],
+      "payable": false,
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "payable": false,
+      "stateMutability": "nonpayable",
+      "type": "constructor"
+    },
+    {
+      "anonymous": false,
+      "inputs": [
+        {
+          "indexed": true,
+          "name": "_from",
+          "type": "address"
+        },
+        {
+          "indexed": true,
+          "name": "_to",
+          "type": "address"
+        },
+        {
+          "indexed": false,
+          "name": "_value",
+          "type": "uint256"
+        }
+      ],
+      "name": "Transfer",
+      "type": "event"
+    }
+  ],
+  "bytecode": "0x6060604052341561000f57600080fd5b6127106000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506103c5806100636000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637bd703e81461005c57806390b98a11146100a9578063f8b2cb4f14610103575b600080fd5b341561006757600080fd5b610093600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610150565b6040518082815260200191505060405180910390f35b34156100b457600080fd5b6100e9600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506101f8565b604051808215151515815260200191505060405180910390f35b341561010e57600080fd5b61013a600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610351565b6040518082815260200191505060405180910390f35b600073__ConvertLib____________________________6396e4ee3d61017584610351565b60026000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808381526020018281526020019250505060206040518083038186803b15156101d657600080fd5b6102c65a03f415156101e757600080fd5b505050604051805190509050919050565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610249576000905061034b565b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190505b92915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490509190505600a165627a7a72305820f791829bf0c920a6d43123cac9b9894757ddc838c17efbad6d56773d6e3dcf4c0029",
+  "deployedBytecode": "0x606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637bd703e81461005c57806390b98a11146100a9578063f8b2cb4f14610103575b600080fd5b341561006757600080fd5b610093600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610150565b6040518082815260200191505060405180910390f35b34156100b457600080fd5b6100e9600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506101f8565b604051808215151515815260200191505060405180910390f35b341561010e57600080fd5b61013a600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610351565b6040518082815260200191505060405180910390f35b600073__ConvertLib____________________________6396e4ee3d61017584610351565b60026000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808381526020018281526020019250505060206040518083038186803b15156101d657600080fd5b6102c65a03f415156101e757600080fd5b505050604051805190509050919050565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610249576000905061034b565b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190505b92915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490509190505600a165627a7a72305820f791829bf0c920a6d43123cac9b9894757ddc838c17efbad6d56773d6e3dcf4c0029",
+  "sourceMap": "315:675:1:-;;;452:62;;;;;;;;505:5;483:8;:19;492:9;483:19;;;;;;;;;;;;;;;:27;;;;315:675;;;;;;",
+  "deployedSourceMap": "315:675:1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;779:117;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;517:259;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;899:89;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;779:117;838:4;854:10;:18;873:16;884:4;873:10;:16::i;:::-;890:1;854:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;847:45;;779:117;;;:::o;517:259::-;581:15;629:6;606:8;:20;615:10;606:20;;;;;;;;;;;;;;;;:29;602:47;;;644:5;637:12;;;;602:47;677:6;653:8;:20;662:10;653:20;;;;;;;;;;;;;;;;:30;;;;;;;;;;;709:6;687:8;:18;696:8;687:18;;;;;;;;;;;;;;;;:28;;;;;;;;;;;740:8;719:38;;728:10;719:38;;;750:6;719:38;;;;;;;;;;;;;;;;;;768:4;761:11;;517:259;;;;;:::o;899:89::-;953:4;970:8;:14;979:4;970:14;;;;;;;;;;;;;;;;963:21;;899:89;;;:::o",
+  "source": "pragma solidity ^0.4.2;\n\nimport \"./ConvertLib.sol\";\n\n// This is just a simple example of a coin-like contract.\n// It is not standards compatible and cannot be expected to talk to other\n// coin/token contracts. If you want to create a standards-compliant\n// token, see: https://github.com/ConsenSys/Tokens. Cheers!\n\ncontract MetaCoin {\n\tmapping (address => uint) balances;\n\n\tevent Transfer(address indexed _from, address indexed _to, uint256 _value);\n\n\tfunction MetaCoin() public {\n\t\tbalances[tx.origin] = 10000;\n\t}\n\n\tfunction sendCoin(address receiver, uint amount) public returns(bool sufficient) {\n\t\tif (balances[msg.sender] < amount) return false;\n\t\tbalances[msg.sender] -= amount;\n\t\tbalances[receiver] += amount;\n\t\tTransfer(msg.sender, receiver, amount);\n\t\treturn true;\n\t}\n\n\tfunction getBalanceInEth(address addr) view public returns(uint){\n\t\treturn ConvertLib.convert(getBalance(addr),2);\n\t}\n\n\tfunction getBalance(address addr) view public returns(uint) {\n\t\treturn balances[addr];\n\t}\n}\n",
+  "sourcePath": "/Users/ezra/Developer/blockchain/truffle_webpack/contracts/MetaCoin.sol",
+  "ast": {
+    "attributes": {
+      "absolutePath": "/Users/ezra/Developer/blockchain/truffle_webpack/contracts/MetaCoin.sol",
+      "exportedSymbols": {
+        "MetaCoin": [
+          112
+        ]
+      }
+    },
+    "children": [
+      {
+        "attributes": {
+          "literals": [
+            "solidity",
+            "^",
+            "0.4",
+            ".2"
+          ]
+        },
+        "id": 18,
+        "name": "PragmaDirective",
+        "src": "0:23:1"
+      },
+      {
+        "attributes": {
+          "SourceUnit": 17,
+          "absolutePath": "/Users/ezra/Developer/blockchain/truffle_webpack/contracts/ConvertLib.sol",
+          "file": "./ConvertLib.sol",
+          "scope": 113,
+          "symbolAliases": [
+            null
+          ],
+          "unitAlias": ""
+        },
+        "id": 19,
+        "name": "ImportDirective",
+        "src": "25:26:1"
+      },
+      {
+        "attributes": {
+          "baseContracts": [
+            null
+          ],
+          "contractDependencies": [
+            null
+          ],
+          "contractKind": "contract",
+          "documentation": null,
+          "fullyImplemented": true,
+          "linearizedBaseContracts": [
+            112
+          ],
+          "name": "MetaCoin",
+          "scope": 113
+        },
+        "children": [
+          {
+            "attributes": {
+              "constant": false,
+              "name": "balances",
+              "scope": 112,
+              "stateVariable": true,
+              "storageLocation": "default",
+              "type": "mapping(address => uint256)",
+              "value": null,
+              "visibility": "internal"
+            },
+            "children": [
+              {
+                "attributes": {
+                  "type": "mapping(address => uint256)"
+                },
+                "children": [
+                  {
+                    "attributes": {
+                      "name": "address",
+                      "type": "address"
+                    },
+                    "id": 20,
+                    "name": "ElementaryTypeName",
+                    "src": "345:7:1"
+                  },
+                  {
+                    "attributes": {
+                      "name": "uint",
+                      "type": "uint256"
+                    },
+                    "id": 21,
+                    "name": "ElementaryTypeName",
+                    "src": "356:4:1"
+                  }
+                ],
+                "id": 22,
+                "name": "Mapping",
+                "src": "336:25:1"
+              }
+            ],
+            "id": 23,
+            "name": "VariableDeclaration",
+            "src": "336:34:1"
+          },
+          {
+            "attributes": {
+              "anonymous": false,
+              "name": "Transfer"
+            },
+            "children": [
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "indexed": true,
+                      "name": "_from",
+                      "scope": 31,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "address",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "address",
+                          "type": "address"
+                        },
+                        "id": 24,
+                        "name": "ElementaryTypeName",
+                        "src": "389:7:1"
+                      }
+                    ],
+                    "id": 25,
+                    "name": "VariableDeclaration",
+                    "src": "389:21:1"
+                  },
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "indexed": true,
+                      "name": "_to",
+                      "scope": 31,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "address",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "address",
+                          "type": "address"
+                        },
+                        "id": 26,
+                        "name": "ElementaryTypeName",
+                        "src": "412:7:1"
+                      }
+                    ],
+                    "id": 27,
+                    "name": "VariableDeclaration",
+                    "src": "412:19:1"
+                  },
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "indexed": false,
+                      "name": "_value",
+                      "scope": 31,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "uint256",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "uint256",
+                          "type": "uint256"
+                        },
+                        "id": 28,
+                        "name": "ElementaryTypeName",
+                        "src": "433:7:1"
+                      }
+                    ],
+                    "id": 29,
+                    "name": "VariableDeclaration",
+                    "src": "433:14:1"
+                  }
+                ],
+                "id": 30,
+                "name": "ParameterList",
+                "src": "388:60:1"
+              }
+            ],
+            "id": 31,
+            "name": "EventDefinition",
+            "src": "374:75:1"
+          },
+          {
+            "attributes": {
+              "constant": false,
+              "implemented": true,
+              "isConstructor": true,
+              "modifiers": [
+                null
+              ],
+              "name": "MetaCoin",
+              "payable": false,
+              "scope": 112,
+              "stateMutability": "nonpayable",
+              "superFunction": null,
+              "visibility": "public"
+            },
+            "children": [
+              {
+                "attributes": {
+                  "parameters": [
+                    null
+                  ]
+                },
+                "children": [],
+                "id": 32,
+                "name": "ParameterList",
+                "src": "469:2:1"
+              },
+              {
+                "attributes": {
+                  "parameters": [
+                    null
+                  ]
+                },
+                "children": [],
+                "id": 33,
+                "name": "ParameterList",
+                "src": "479:0:1"
+              },
+              {
+                "children": [
+                  {
+                    "children": [
+                      {
+                        "attributes": {
+                          "argumentTypes": null,
+                          "isConstant": false,
+                          "isLValue": false,
+                          "isPure": false,
+                          "lValueRequested": false,
+                          "operator": "=",
+                          "type": "uint256"
+                        },
+                        "children": [
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "isConstant": false,
+                              "isLValue": true,
+                              "isPure": false,
+                              "lValueRequested": true,
+                              "type": "uint256"
+                            },
+                            "children": [
+                              {
+                                "attributes": {
+                                  "argumentTypes": null,
+                                  "overloadedDeclarations": [
+                                    null
+                                  ],
+                                  "referencedDeclaration": 23,
+                                  "type": "mapping(address => uint256)",
+                                  "value": "balances"
+                                },
+                                "id": 34,
+                                "name": "Identifier",
+                                "src": "483:8:1"
+                              },
+                              {
+                                "attributes": {
+                                  "argumentTypes": null,
+                                  "isConstant": false,
+                                  "isLValue": false,
+                                  "isPure": false,
+                                  "lValueRequested": false,
+                                  "member_name": "origin",
+                                  "referencedDeclaration": null,
+                                  "type": "address"
+                                },
+                                "children": [
+                                  {
+                                    "attributes": {
+                                      "argumentTypes": null,
+                                      "overloadedDeclarations": [
+                                        null
+                                      ],
+                                      "referencedDeclaration": 191,
+                                      "type": "tx",
+                                      "value": "tx"
+                                    },
+                                    "id": 35,
+                                    "name": "Identifier",
+                                    "src": "492:2:1"
+                                  }
+                                ],
+                                "id": 36,
+                                "name": "MemberAccess",
+                                "src": "492:9:1"
+                              }
+                            ],
+                            "id": 37,
+                            "name": "IndexAccess",
+                            "src": "483:19:1"
+                          },
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "hexvalue": "3130303030",
+                              "isConstant": false,
+                              "isLValue": false,
+                              "isPure": true,
+                              "lValueRequested": false,
+                              "subdenomination": null,
+                              "token": "number",
+                              "type": "int_const 10000",
+                              "value": "10000"
+                            },
+                            "id": 38,
+                            "name": "Literal",
+                            "src": "505:5:1"
+                          }
+                        ],
+                        "id": 39,
+                        "name": "Assignment",
+                        "src": "483:27:1"
+                      }
+                    ],
+                    "id": 40,
+                    "name": "ExpressionStatement",
+                    "src": "483:27:1"
+                  }
+                ],
+                "id": 41,
+                "name": "Block",
+                "src": "479:35:1"
+              }
+            ],
+            "id": 42,
+            "name": "FunctionDefinition",
+            "src": "452:62:1"
+          },
+          {
+            "attributes": {
+              "constant": false,
+              "implemented": true,
+              "isConstructor": false,
+              "modifiers": [
+                null
+              ],
+              "name": "sendCoin",
+              "payable": false,
+              "scope": 112,
+              "stateMutability": "nonpayable",
+              "superFunction": null,
+              "visibility": "public"
+            },
+            "children": [
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "name": "receiver",
+                      "scope": 83,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "address",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "address",
+                          "type": "address"
+                        },
+                        "id": 43,
+                        "name": "ElementaryTypeName",
+                        "src": "535:7:1"
+                      }
+                    ],
+                    "id": 44,
+                    "name": "VariableDeclaration",
+                    "src": "535:16:1"
+                  },
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "name": "amount",
+                      "scope": 83,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "uint256",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "uint",
+                          "type": "uint256"
+                        },
+                        "id": 45,
+                        "name": "ElementaryTypeName",
+                        "src": "553:4:1"
+                      }
+                    ],
+                    "id": 46,
+                    "name": "VariableDeclaration",
+                    "src": "553:11:1"
+                  }
+                ],
+                "id": 47,
+                "name": "ParameterList",
+                "src": "534:31:1"
+              },
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "name": "sufficient",
+                      "scope": 83,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "bool",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "bool",
+                          "type": "bool"
+                        },
+                        "id": 48,
+                        "name": "ElementaryTypeName",
+                        "src": "581:4:1"
+                      }
+                    ],
+                    "id": 49,
+                    "name": "VariableDeclaration",
+                    "src": "581:15:1"
+                  }
+                ],
+                "id": 50,
+                "name": "ParameterList",
+                "src": "580:17:1"
+              },
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "falseBody": null
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "argumentTypes": null,
+                          "commonType": {
+                            "typeIdentifier": "t_uint256",
+                            "typeString": "uint256"
+                          },
+                          "isConstant": false,
+                          "isLValue": false,
+                          "isPure": false,
+                          "lValueRequested": false,
+                          "operator": "<",
+                          "type": "bool"
+                        },
+                        "children": [
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "isConstant": false,
+                              "isLValue": true,
+                              "isPure": false,
+                              "lValueRequested": false,
+                              "type": "uint256"
+                            },
+                            "children": [
+                              {
+                                "attributes": {
+                                  "argumentTypes": null,
+                                  "overloadedDeclarations": [
+                                    null
+                                  ],
+                                  "referencedDeclaration": 23,
+                                  "type": "mapping(address => uint256)",
+                                  "value": "balances"
+                                },
+                                "id": 51,
+                                "name": "Identifier",
+                                "src": "606:8:1"
+                              },
+                              {
+                                "attributes": {
+                                  "argumentTypes": null,
+                                  "isConstant": false,
+                                  "isLValue": false,
+                                  "isPure": false,
+                                  "lValueRequested": false,
+                                  "member_name": "sender",
+                                  "referencedDeclaration": null,
+                                  "type": "address"
+                                },
+                                "children": [
+                                  {
+                                    "attributes": {
+                                      "argumentTypes": null,
+                                      "overloadedDeclarations": [
+                                        null
+                                      ],
+                                      "referencedDeclaration": 181,
+                                      "type": "msg",
+                                      "value": "msg"
+                                    },
+                                    "id": 52,
+                                    "name": "Identifier",
+                                    "src": "615:3:1"
+                                  }
+                                ],
+                                "id": 53,
+                                "name": "MemberAccess",
+                                "src": "615:10:1"
+                              }
+                            ],
+                            "id": 54,
+                            "name": "IndexAccess",
+                            "src": "606:20:1"
+                          },
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "overloadedDeclarations": [
+                                null
+                              ],
+                              "referencedDeclaration": 46,
+                              "type": "uint256",
+                              "value": "amount"
+                            },
+                            "id": 55,
+                            "name": "Identifier",
+                            "src": "629:6:1"
+                          }
+                        ],
+                        "id": 56,
+                        "name": "BinaryOperation",
+                        "src": "606:29:1"
+                      },
+                      {
+                        "attributes": {
+                          "functionReturnParameters": 50
+                        },
+                        "children": [
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "hexvalue": "66616c7365",
+                              "isConstant": false,
+                              "isLValue": false,
+                              "isPure": true,
+                              "lValueRequested": false,
+                              "subdenomination": null,
+                              "token": "bool",
+                              "type": "bool",
+                              "value": "false"
+                            },
+                            "id": 57,
+                            "name": "Literal",
+                            "src": "644:5:1"
+                          }
+                        ],
+                        "id": 58,
+                        "name": "Return",
+                        "src": "637:12:1"
+                      }
+                    ],
+                    "id": 59,
+                    "name": "IfStatement",
+                    "src": "602:47:1"
+                  },
+                  {
+                    "children": [
+                      {
+                        "attributes": {
+                          "argumentTypes": null,
+                          "isConstant": false,
+                          "isLValue": false,
+                          "isPure": false,
+                          "lValueRequested": false,
+                          "operator": "-=",
+                          "type": "uint256"
+                        },
+                        "children": [
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "isConstant": false,
+                              "isLValue": true,
+                              "isPure": false,
+                              "lValueRequested": true,
+                              "type": "uint256"
+                            },
+                            "children": [
+                              {
+                                "attributes": {
+                                  "argumentTypes": null,
+                                  "overloadedDeclarations": [
+                                    null
+                                  ],
+                                  "referencedDeclaration": 23,
+                                  "type": "mapping(address => uint256)",
+                                  "value": "balances"
+                                },
+                                "id": 60,
+                                "name": "Identifier",
+                                "src": "653:8:1"
+                              },
+                              {
+                                "attributes": {
+                                  "argumentTypes": null,
+                                  "isConstant": false,
+                                  "isLValue": false,
+                                  "isPure": false,
+                                  "lValueRequested": false,
+                                  "member_name": "sender",
+                                  "referencedDeclaration": null,
+                                  "type": "address"
+                                },
+                                "children": [
+                                  {
+                                    "attributes": {
+                                      "argumentTypes": null,
+                                      "overloadedDeclarations": [
+                                        null
+                                      ],
+                                      "referencedDeclaration": 181,
+                                      "type": "msg",
+                                      "value": "msg"
+                                    },
+                                    "id": 61,
+                                    "name": "Identifier",
+                                    "src": "662:3:1"
+                                  }
+                                ],
+                                "id": 62,
+                                "name": "MemberAccess",
+                                "src": "662:10:1"
+                              }
+                            ],
+                            "id": 63,
+                            "name": "IndexAccess",
+                            "src": "653:20:1"
+                          },
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "overloadedDeclarations": [
+                                null
+                              ],
+                              "referencedDeclaration": 46,
+                              "type": "uint256",
+                              "value": "amount"
+                            },
+                            "id": 64,
+                            "name": "Identifier",
+                            "src": "677:6:1"
+                          }
+                        ],
+                        "id": 65,
+                        "name": "Assignment",
+                        "src": "653:30:1"
+                      }
+                    ],
+                    "id": 66,
+                    "name": "ExpressionStatement",
+                    "src": "653:30:1"
+                  },
+                  {
+                    "children": [
+                      {
+                        "attributes": {
+                          "argumentTypes": null,
+                          "isConstant": false,
+                          "isLValue": false,
+                          "isPure": false,
+                          "lValueRequested": false,
+                          "operator": "+=",
+                          "type": "uint256"
+                        },
+                        "children": [
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "isConstant": false,
+                              "isLValue": true,
+                              "isPure": false,
+                              "lValueRequested": true,
+                              "type": "uint256"
+                            },
+                            "children": [
+                              {
+                                "attributes": {
+                                  "argumentTypes": null,
+                                  "overloadedDeclarations": [
+                                    null
+                                  ],
+                                  "referencedDeclaration": 23,
+                                  "type": "mapping(address => uint256)",
+                                  "value": "balances"
+                                },
+                                "id": 67,
+                                "name": "Identifier",
+                                "src": "687:8:1"
+                              },
+                              {
+                                "attributes": {
+                                  "argumentTypes": null,
+                                  "overloadedDeclarations": [
+                                    null
+                                  ],
+                                  "referencedDeclaration": 44,
+                                  "type": "address",
+                                  "value": "receiver"
+                                },
+                                "id": 68,
+                                "name": "Identifier",
+                                "src": "696:8:1"
+                              }
+                            ],
+                            "id": 69,
+                            "name": "IndexAccess",
+                            "src": "687:18:1"
+                          },
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "overloadedDeclarations": [
+                                null
+                              ],
+                              "referencedDeclaration": 46,
+                              "type": "uint256",
+                              "value": "amount"
+                            },
+                            "id": 70,
+                            "name": "Identifier",
+                            "src": "709:6:1"
+                          }
+                        ],
+                        "id": 71,
+                        "name": "Assignment",
+                        "src": "687:28:1"
+                      }
+                    ],
+                    "id": 72,
+                    "name": "ExpressionStatement",
+                    "src": "687:28:1"
+                  },
+                  {
+                    "children": [
+                      {
+                        "attributes": {
+                          "argumentTypes": null,
+                          "isConstant": false,
+                          "isLValue": false,
+                          "isPure": false,
+                          "isStructConstructorCall": false,
+                          "lValueRequested": false,
+                          "names": [
+                            null
+                          ],
+                          "type": "tuple()",
+                          "type_conversion": false
+                        },
+                        "children": [
+                          {
+                            "attributes": {
+                              "argumentTypes": [
+                                {
+                                  "typeIdentifier": "t_address",
+                                  "typeString": "address"
+                                },
+                                {
+                                  "typeIdentifier": "t_address",
+                                  "typeString": "address"
+                                },
+                                {
+                                  "typeIdentifier": "t_uint256",
+                                  "typeString": "uint256"
+                                }
+                              ],
+                              "overloadedDeclarations": [
+                                null
+                              ],
+                              "referencedDeclaration": 31,
+                              "type": "function (address,address,uint256)",
+                              "value": "Transfer"
+                            },
+                            "id": 73,
+                            "name": "Identifier",
+                            "src": "719:8:1"
+                          },
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "isConstant": false,
+                              "isLValue": false,
+                              "isPure": false,
+                              "lValueRequested": false,
+                              "member_name": "sender",
+                              "referencedDeclaration": null,
+                              "type": "address"
+                            },
+                            "children": [
+                              {
+                                "attributes": {
+                                  "argumentTypes": null,
+                                  "overloadedDeclarations": [
+                                    null
+                                  ],
+                                  "referencedDeclaration": 181,
+                                  "type": "msg",
+                                  "value": "msg"
+                                },
+                                "id": 74,
+                                "name": "Identifier",
+                                "src": "728:3:1"
+                              }
+                            ],
+                            "id": 75,
+                            "name": "MemberAccess",
+                            "src": "728:10:1"
+                          },
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "overloadedDeclarations": [
+                                null
+                              ],
+                              "referencedDeclaration": 44,
+                              "type": "address",
+                              "value": "receiver"
+                            },
+                            "id": 76,
+                            "name": "Identifier",
+                            "src": "740:8:1"
+                          },
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "overloadedDeclarations": [
+                                null
+                              ],
+                              "referencedDeclaration": 46,
+                              "type": "uint256",
+                              "value": "amount"
+                            },
+                            "id": 77,
+                            "name": "Identifier",
+                            "src": "750:6:1"
+                          }
+                        ],
+                        "id": 78,
+                        "name": "FunctionCall",
+                        "src": "719:38:1"
+                      }
+                    ],
+                    "id": 79,
+                    "name": "ExpressionStatement",
+                    "src": "719:38:1"
+                  },
+                  {
+                    "attributes": {
+                      "functionReturnParameters": 50
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "argumentTypes": null,
+                          "hexvalue": "74727565",
+                          "isConstant": false,
+                          "isLValue": false,
+                          "isPure": true,
+                          "lValueRequested": false,
+                          "subdenomination": null,
+                          "token": "bool",
+                          "type": "bool",
+                          "value": "true"
+                        },
+                        "id": 80,
+                        "name": "Literal",
+                        "src": "768:4:1"
+                      }
+                    ],
+                    "id": 81,
+                    "name": "Return",
+                    "src": "761:11:1"
+                  }
+                ],
+                "id": 82,
+                "name": "Block",
+                "src": "598:178:1"
+              }
+            ],
+            "id": 83,
+            "name": "FunctionDefinition",
+            "src": "517:259:1"
+          },
+          {
+            "attributes": {
+              "constant": true,
+              "implemented": true,
+              "isConstructor": false,
+              "modifiers": [
+                null
+              ],
+              "name": "getBalanceInEth",
+              "payable": false,
+              "scope": 112,
+              "stateMutability": "view",
+              "superFunction": null,
+              "visibility": "public"
+            },
+            "children": [
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "name": "addr",
+                      "scope": 99,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "address",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "address",
+                          "type": "address"
+                        },
+                        "id": 84,
+                        "name": "ElementaryTypeName",
+                        "src": "804:7:1"
+                      }
+                    ],
+                    "id": 85,
+                    "name": "VariableDeclaration",
+                    "src": "804:12:1"
+                  }
+                ],
+                "id": 86,
+                "name": "ParameterList",
+                "src": "803:14:1"
+              },
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "name": "",
+                      "scope": 99,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "uint256",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "uint",
+                          "type": "uint256"
+                        },
+                        "id": 87,
+                        "name": "ElementaryTypeName",
+                        "src": "838:4:1"
+                      }
+                    ],
+                    "id": 88,
+                    "name": "VariableDeclaration",
+                    "src": "838:4:1"
+                  }
+                ],
+                "id": 89,
+                "name": "ParameterList",
+                "src": "837:6:1"
+              },
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "functionReturnParameters": 89
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "argumentTypes": null,
+                          "isConstant": false,
+                          "isLValue": false,
+                          "isPure": false,
+                          "isStructConstructorCall": false,
+                          "lValueRequested": false,
+                          "names": [
+                            null
+                          ],
+                          "type": "uint256",
+                          "type_conversion": false
+                        },
+                        "children": [
+                          {
+                            "attributes": {
+                              "argumentTypes": [
+                                {
+                                  "typeIdentifier": "t_uint256",
+                                  "typeString": "uint256"
+                                },
+                                {
+                                  "typeIdentifier": "t_rational_2_by_1",
+                                  "typeString": "int_const 2"
+                                }
+                              ],
+                              "isConstant": false,
+                              "isLValue": false,
+                              "isPure": false,
+                              "lValueRequested": false,
+                              "member_name": "convert",
+                              "referencedDeclaration": 15,
+                              "type": "function (uint256,uint256) pure returns (uint256)"
+                            },
+                            "children": [
+                              {
+                                "attributes": {
+                                  "argumentTypes": null,
+                                  "overloadedDeclarations": [
+                                    null
+                                  ],
+                                  "referencedDeclaration": 16,
+                                  "type": "type(library ConvertLib)",
+                                  "value": "ConvertLib"
+                                },
+                                "id": 90,
+                                "name": "Identifier",
+                                "src": "854:10:1"
+                              }
+                            ],
+                            "id": 91,
+                            "name": "MemberAccess",
+                            "src": "854:18:1"
+                          },
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "isConstant": false,
+                              "isLValue": false,
+                              "isPure": false,
+                              "isStructConstructorCall": false,
+                              "lValueRequested": false,
+                              "names": [
+                                null
+                              ],
+                              "type": "uint256",
+                              "type_conversion": false
+                            },
+                            "children": [
+                              {
+                                "attributes": {
+                                  "argumentTypes": [
+                                    {
+                                      "typeIdentifier": "t_address",
+                                      "typeString": "address"
+                                    }
+                                  ],
+                                  "overloadedDeclarations": [
+                                    null
+                                  ],
+                                  "referencedDeclaration": 111,
+                                  "type": "function (address) view returns (uint256)",
+                                  "value": "getBalance"
+                                },
+                                "id": 92,
+                                "name": "Identifier",
+                                "src": "873:10:1"
+                              },
+                              {
+                                "attributes": {
+                                  "argumentTypes": null,
+                                  "overloadedDeclarations": [
+                                    null
+                                  ],
+                                  "referencedDeclaration": 85,
+                                  "type": "address",
+                                  "value": "addr"
+                                },
+                                "id": 93,
+                                "name": "Identifier",
+                                "src": "884:4:1"
+                              }
+                            ],
+                            "id": 94,
+                            "name": "FunctionCall",
+                            "src": "873:16:1"
+                          },
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "hexvalue": "32",
+                              "isConstant": false,
+                              "isLValue": false,
+                              "isPure": true,
+                              "lValueRequested": false,
+                              "subdenomination": null,
+                              "token": "number",
+                              "type": "int_const 2",
+                              "value": "2"
+                            },
+                            "id": 95,
+                            "name": "Literal",
+                            "src": "890:1:1"
+                          }
+                        ],
+                        "id": 96,
+                        "name": "FunctionCall",
+                        "src": "854:38:1"
+                      }
+                    ],
+                    "id": 97,
+                    "name": "Return",
+                    "src": "847:45:1"
+                  }
+                ],
+                "id": 98,
+                "name": "Block",
+                "src": "843:53:1"
+              }
+            ],
+            "id": 99,
+            "name": "FunctionDefinition",
+            "src": "779:117:1"
+          },
+          {
+            "attributes": {
+              "constant": true,
+              "implemented": true,
+              "isConstructor": false,
+              "modifiers": [
+                null
+              ],
+              "name": "getBalance",
+              "payable": false,
+              "scope": 112,
+              "stateMutability": "view",
+              "superFunction": null,
+              "visibility": "public"
+            },
+            "children": [
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "name": "addr",
+                      "scope": 111,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "address",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "address",
+                          "type": "address"
+                        },
+                        "id": 100,
+                        "name": "ElementaryTypeName",
+                        "src": "919:7:1"
+                      }
+                    ],
+                    "id": 101,
+                    "name": "VariableDeclaration",
+                    "src": "919:12:1"
+                  }
+                ],
+                "id": 102,
+                "name": "ParameterList",
+                "src": "918:14:1"
+              },
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "constant": false,
+                      "name": "",
+                      "scope": 111,
+                      "stateVariable": false,
+                      "storageLocation": "default",
+                      "type": "uint256",
+                      "value": null,
+                      "visibility": "internal"
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "name": "uint",
+                          "type": "uint256"
+                        },
+                        "id": 103,
+                        "name": "ElementaryTypeName",
+                        "src": "953:4:1"
+                      }
+                    ],
+                    "id": 104,
+                    "name": "VariableDeclaration",
+                    "src": "953:4:1"
+                  }
+                ],
+                "id": 105,
+                "name": "ParameterList",
+                "src": "952:6:1"
+              },
+              {
+                "children": [
+                  {
+                    "attributes": {
+                      "functionReturnParameters": 105
+                    },
+                    "children": [
+                      {
+                        "attributes": {
+                          "argumentTypes": null,
+                          "isConstant": false,
+                          "isLValue": true,
+                          "isPure": false,
+                          "lValueRequested": false,
+                          "type": "uint256"
+                        },
+                        "children": [
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "overloadedDeclarations": [
+                                null
+                              ],
+                              "referencedDeclaration": 23,
+                              "type": "mapping(address => uint256)",
+                              "value": "balances"
+                            },
+                            "id": 106,
+                            "name": "Identifier",
+                            "src": "970:8:1"
+                          },
+                          {
+                            "attributes": {
+                              "argumentTypes": null,
+                              "overloadedDeclarations": [
+                                null
+                              ],
+                              "referencedDeclaration": 101,
+                              "type": "address",
+                              "value": "addr"
+                            },
+                            "id": 107,
+                            "name": "Identifier",
+                            "src": "979:4:1"
+                          }
+                        ],
+                        "id": 108,
+                        "name": "IndexAccess",
+                        "src": "970:14:1"
+                      }
+                    ],
+                    "id": 109,
+                    "name": "Return",
+                    "src": "963:21:1"
+                  }
+                ],
+                "id": 110,
+                "name": "Block",
+                "src": "959:29:1"
+              }
+            ],
+            "id": 111,
+            "name": "FunctionDefinition",
+            "src": "899:89:1"
+          }
+        ],
+        "id": 112,
+        "name": "ContractDefinition",
+        "src": "315:675:1"
+      }
+    ],
+    "id": 113,
+    "name": "SourceUnit",
+    "src": "0:991:1"
+  },
+  "compiler": {
+    "name": "solc",
+    "version": "0.4.18+commit.9cf6e910.Emscripten.clang"
+  },
+  "networks": {
+    "4": {
+      "events": {},
+      "links": {
+        "ConvertLib": "0x14d00a701a2f0d4d65eebaf191f4f60bbaa1da36"
+      },
+      "address": "0xaea9d31a4aeda9e510f7d85559261c16ea0b6b8b"
+    },
+    "4447": {
+      "events": {},
+      "links": {
+        "ConvertLib": "0xcfeb869f69431e42cdb54a4f4f105c19c080a601"
+      },
+      "address": "0x254dffcd3277c0b1660f6d42efbb754edababc2b"
+    }
+  },
+  "schemaVersion": "1.0.1",
+  "updatedAt": "2017-11-07T20:44:02.307Z"
+}
\ No newline at end of file
diff --git a/console/src/main/java/org/web3j/console/Runner.java b/console/src/main/java/org/web3j/console/Runner.java
index 5a3f95119..f52c83bf8 100644
--- a/console/src/main/java/org/web3j/console/Runner.java
+++ b/console/src/main/java/org/web3j/console/Runner.java
@@ -2,6 +2,7 @@
 
 import org.web3j.codegen.Console;
 import org.web3j.codegen.SolidityFunctionWrapperGenerator;
+import org.web3j.codegen.TruffleJsonFunctionWrapperGenerator;
 import org.web3j.utils.Version;
 
 import static org.web3j.utils.Collection.tail;
@@ -36,6 +37,9 @@ public static void main(String[] args) throws Exception {
                 case "solidity":
                     SolidityFunctionWrapperGenerator.run(tail(args));
                     break;
+                case "truffle":
+                    TruffleJsonFunctionWrapperGenerator.run(tail(args));
+                    break;
                 case "version":
                     Console.exitSuccess("Version: " + Version.getVersion() + "\n"
                             + "Build timestamp: " + Version.getTimestamp());
diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/AbiDefinition.java b/core/src/main/java/org/web3j/protocol/core/methods/response/AbiDefinition.java
index ecdab2076..91d7e44c5 100644
--- a/core/src/main/java/org/web3j/protocol/core/methods/response/AbiDefinition.java
+++ b/core/src/main/java/org/web3j/protocol/core/methods/response/AbiDefinition.java
@@ -16,19 +16,44 @@ public class AbiDefinition {
     private String type;
     private boolean payable;
 
+    /**
+     * The stateMutability function modifier.
+     * <p>this does not factor into the <code>#hashCode()</code> or <code>#equals()</code> logic
+     * since multiple functions with the same signature that only differ in mutability are not
+     * allowed in Solidity.</p>
+     * <p>
+     *     Valid values are:
+     *     <ul>
+     *         <li>pure</li>
+     *         <li>view</li>
+     *         <li>nonpayable</li>
+     *         <li>payable</li>
+     *     </ul>
+     * </p>
+     */
+    private String stateMutability;
+    
     public AbiDefinition() {
     }
 
     public AbiDefinition(boolean constant, List<NamedType> inputs, String name,
                          List<NamedType> outputs, String type, boolean payable) {
+        this(constant, inputs, name, outputs, type, payable, null);
+    }
+
+    public AbiDefinition(boolean constant, List<NamedType> inputs, String name,
+            List<NamedType> outputs, String type, boolean payable,
+            String stateMutability) {
         this.constant = constant;
         this.inputs = inputs;
         this.name = name;
         this.outputs = outputs;
         this.type = type;
         this.payable = payable;
+        this.stateMutability = stateMutability;
     }
 
+
     public boolean isConstant() {
         return constant;
     }
@@ -77,6 +102,14 @@ public void setPayable(boolean payable) {
         this.payable = payable;
     }
 
+    public String getStateMutability() {
+        return stateMutability;
+    }
+
+    public void setStateMutability(String stateMutability) {
+        this.stateMutability = stateMutability;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) {
@@ -106,6 +139,11 @@ public boolean equals(Object o) {
                 ? !getOutputs().equals(that.getOutputs()) : that.getOutputs() != null) {
             return false;
         }
+        if (getStateMutability() != null
+                ? !getStateMutability().equals(that.getStateMutability())
+                : that.getStateMutability() != null) {
+            return false;
+        }
         return getType() != null
                 ? getType().equals(that.getType()) : that.getType() == null;
     }
@@ -118,6 +156,7 @@ public int hashCode() {
         result = 31 * result + (getOutputs() != null ? getOutputs().hashCode() : 0);
         result = 31 * result + (getType() != null ? getType().hashCode() : 0);
         result = 31 * result + (isPayable() ? 1 : 0);
+        result = 31 * result + (getStateMutability() != null ? getStateMutability().hashCode() : 0);
         return result;
     }
 
@@ -172,6 +211,7 @@ public boolean equals(Object o) {
             if (isIndexed() != namedType.isIndexed()) {
                 return false;
             }
+
             if (getName() != null
                     ? !getName().equals(namedType.getName()) : namedType.getName() != null) {
                 return false;
diff --git a/core/src/main/java/org/web3j/tx/Contract.java b/core/src/main/java/org/web3j/tx/Contract.java
index ee9af948d..8f6f4e481 100644
--- a/core/src/main/java/org/web3j/tx/Contract.java
+++ b/core/src/main/java/org/web3j/tx/Contract.java
@@ -4,7 +4,9 @@
 import java.lang.reflect.Constructor;
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
 import org.web3j.abi.EventEncoder;
@@ -41,6 +43,7 @@ public abstract class Contract extends ManagedTransaction {
     private final BigInteger gasPrice;
     private final BigInteger gasLimit;
     private TransactionReceipt transactionReceipt;
+    private Map<String, String> deployedAddresses;
 
     protected Contract(String contractBinary, String contractAddress,
                        Web3j web3j, TransactionManager transactionManager,
@@ -369,4 +372,31 @@ protected List<EventValues> extractEventParameters(
 
         return values;
     }
+
+    /**
+     * Subclasses should implement this method to return pre-existing addresses for deployed
+     * contracts.
+     *
+     * @param networkId the network id, for example "1" for the main-net, "3" for ropsten, etc.
+     * @return the deployed address of the contract, if known, and null otherwise.
+     */
+    protected String getStaticDeployedAddress(String networkId) {
+        return null;
+    }
+
+    public final void setDeployedAddress(String networkId, String address) {
+        if (deployedAddresses == null) {
+            deployedAddresses = new HashMap<>();
+        }
+        deployedAddresses.put(networkId, address);
+    }
+
+    public final String getDeployedAddress(String networkId) {
+        String addr = null;
+        if (deployedAddresses != null) {
+            addr = deployedAddresses.get(networkId);
+        }
+        return addr == null ? getStaticDeployedAddress(networkId) : addr;
+    }
+
 }
diff --git a/utils/src/main/java/org/web3j/utils/Strings.java b/utils/src/main/java/org/web3j/utils/Strings.java
index 37a1ada2c..7d4376e4d 100644
--- a/utils/src/main/java/org/web3j/utils/Strings.java
+++ b/utils/src/main/java/org/web3j/utils/Strings.java
@@ -47,4 +47,8 @@ public static String zeros(int n) {
     public static String repeat(char value, int n) {
         return new String(new char[n]).replace("\0", String.valueOf(value));
     }
+
+    public static boolean isEmpty(String s) {
+        return s == null || s.length() == 0;
+    }
 }