diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go
index 7bda997a61..e51b44563a 100644
--- a/accounts/abi/bind/bind.go
+++ b/accounts/abi/bind/bind.go
@@ -47,7 +47,7 @@ const (
 // to be used as is in client code, but rather as an intermediate struct which
 // enforces compile time type safety and naming convention opposed to having to
 // manually maintain hard coded strings that break on runtime.
-func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string) (string, error) {
+func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string, aliases map[string]string) (string, error) {
 	// Process each individual contract requested binding
 	contracts := make(map[string]*tmplContract)
 
@@ -74,12 +74,29 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
 			transacts = make(map[string]*tmplMethod)
 			events    = make(map[string]*tmplEvent)
 			structs   = make(map[string]*tmplStruct)
+
+			// identifiers are used to detect duplicated identifier of function
+			// and event. For all calls, transacts and events, abigen will generate
+			// corresponding bindings. However we have to ensure there is no
+			// identifier coliision in the bindings of these categories.
+			callIdentifiers     = make(map[string]bool)
+			transactIdentifiers = make(map[string]bool)
+			eventIdentifiers    = make(map[string]bool)
 		)
 		for _, original := range evmABI.Methods {
 			// Normalize the method for capital cases and non-anonymous inputs/outputs
 			normalized := original
-			normalized.Name = methodNormalizer[lang](original.Name)
-
+			normalizedName := methodNormalizer[lang](alias(aliases, original.Name))
+			// Ensure there is no duplicated identifier
+			var identifiers = callIdentifiers
+			if !original.Const {
+				identifiers = transactIdentifiers
+			}
+			if identifiers[normalizedName] {
+				return "", fmt.Errorf("duplicated identifier \"%s\"(normalized \"%s\"), use --alias for renaming", original.Name, normalizedName)
+			}
+			identifiers[normalizedName] = true
+			normalized.Name = normalizedName
 			normalized.Inputs = make([]abi.Argument, len(original.Inputs))
 			copy(normalized.Inputs, original.Inputs)
 			for j, input := range normalized.Inputs {
@@ -114,7 +131,14 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
 			}
 			// Normalize the event for capital cases and non-anonymous outputs
 			normalized := original
-			normalized.Name = methodNormalizer[lang](original.Name)
+
+			// Ensure there is no duplicated identifier
+			normalizedName := methodNormalizer[lang](alias(aliases, original.Name))
+			if eventIdentifiers[normalizedName] {
+				return "", fmt.Errorf("duplicated identifier \"%s\"(normalized \"%s\"), use --alias for renaming", original.Name, normalizedName)
+			}
+			eventIdentifiers[normalizedName] = true
+			normalized.Name = normalizedName
 
 			normalized.Inputs = make([]abi.Argument, len(original.Inputs))
 			copy(normalized.Inputs, original.Inputs)
@@ -483,6 +507,15 @@ func namedTypeJava(javaKind string, solKind abi.Type) string {
 	}
 }
 
+// alias returns an alias of the given string based on the aliasing rules
+// or returns itself if no rule is matched.
+func alias(aliases map[string]string, n string) string {
+	if alias, exist := aliases[n]; exist {
+		return alias
+	}
+	return n
+}
+
 // methodNormalizer is a name transformer that modifies Solidity method names to
 // conform to target language naming concentions.
 var methodNormalizer = map[Lang]func(string) string{
diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go
index 1db5682833..333b1d5a88 100644
--- a/accounts/abi/bind/bind_test.go
+++ b/accounts/abi/bind/bind_test.go
@@ -38,6 +38,7 @@ var bindTests = []struct {
 	tester   string
 	fsigs    []map[string]string
 	libs     map[string]string
+	aliases  map[string]string
 	types    []string
 }{
 	// Test that the binding is available in combined and separate forms too
@@ -61,6 +62,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Test that all the official sample contracts bind correctly
 	{
@@ -77,6 +79,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	{
 		`Crowdsale`,
@@ -92,6 +95,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	{
 		`DAO`,
@@ -107,6 +111,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Test that named and anonymous inputs are handled correctly
 	{
@@ -143,6 +148,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Test that named and anonymous outputs are handled correctly
 	{
@@ -182,6 +188,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Tests that named, anonymous and indexed events are handled correctly
 	{
@@ -250,6 +257,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Test that contract interactions (deploy, transact and call) generate working code
 	{
@@ -311,6 +319,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Tests that plain values can be properly returned and deserialized
 	{
@@ -356,6 +365,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Tests that tuples can be properly returned and deserialized
 	{
@@ -401,6 +411,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Tests that arrays/slices can be properly returned and deserialized.
 	// Only addresses are tested, remainder just compiled to keep the test small.
@@ -458,6 +469,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Tests that anonymous default methods can be correctly invoked
 	{
@@ -508,6 +520,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Tests that non-existent contracts are reported as such (though only simulator test)
 	{
@@ -547,6 +560,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Tests that gas estimation works for contracts with weird gas mechanics too.
 	{
@@ -602,6 +616,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Test that constant functions can be called from an (optional) specified address
 	{
@@ -655,6 +670,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Tests that methods and returns with underscores inside work correctly.
 	{
@@ -734,6 +750,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	// Tests that logs can be successfully filtered and decoded.
 	{
@@ -955,6 +972,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	{
 		`DeeplyNestedArray`,
@@ -1035,6 +1053,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	{
 		`CallbackParam`,
@@ -1076,6 +1095,7 @@ var bindTests = []struct {
 		},
 		nil,
 		nil,
+		nil,
 	}, {
 		`Tuple`,
 		`
@@ -1219,6 +1239,7 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
 	},
 	{
 		`UseLibrary`,
@@ -1287,6 +1308,7 @@ var bindTests = []struct {
 		map[string]string{
 			"b98c933f0a6ececcd167bd4f9d3299b1a0": "Math",
 		},
+		nil,
 		[]string{"UseLibrary", "Math"},
 	}, {
 		"Overload",
@@ -1381,6 +1403,50 @@ var bindTests = []struct {
 		nil,
 		nil,
 		nil,
+		nil,
+	},
+	{
+		"IdentifierCollision",
+		`
+		pragma solidity >=0.4.19 <0.6.0;
+
+		contract IdentifierCollision {
+			uint public _myVar;
+
+			function MyVar() public view returns (uint) {
+				return _myVar;
+			}
+		}
+		`,
+		[]string{"60806040523480156100115760006000fd5b50610017565b60c3806100256000396000f3fe608060405234801560105760006000fd5b506004361060365760003560e01c806301ad4d8714603c5780634ef1f0ad146058576036565b60006000fd5b60426074565b6040518082815260200191505060405180910390f35b605e607d565b6040518082815260200191505060405180910390f35b60006000505481565b60006000600050549050608b565b9056fea265627a7a7231582067c8d84688b01c4754ba40a2a871cede94ea1f28b5981593ab2a45b46ac43af664736f6c634300050c0032"},
+		[]string{`[{"constant":true,"inputs":[],"name":"MyVar","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_myVar","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]`},
+		`
+		"math/big"
+
+		"github.com/ethereum/go-ethereum/accounts/abi/bind"
+		"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
+		"github.com/ethereum/go-ethereum/crypto"
+		"github.com/ethereum/go-ethereum/core"
+		`,
+		`
+		// Initialize test accounts
+		key, _ := crypto.GenerateKey()
+		addr := crypto.PubkeyToAddress(key.PublicKey)
+
+		// Deploy registrar contract
+		sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000)
+		defer sim.Close()
+
+		transactOpts := bind.NewKeyedTransactor(key)
+		_, _, _, err := DeployIdentifierCollision(transactOpts, sim)
+		if err != nil {
+			t.Fatalf("failed to deploy contract: %v", err)
+		}
+		`,
+		nil,
+		nil,
+		map[string]string{"_myVar": "pubVar"}, // alias MyVar to PubVar
+		nil,
 	},
 }
 
@@ -1412,7 +1478,7 @@ func TestGolangBindings(t *testing.T) {
 			types = []string{tt.name}
 		}
 		// Generate the binding and create a Go source file in the workspace
-		bind, err := Bind(types, tt.abi, tt.bytecode, tt.fsigs, "bindtest", LangGo, tt.libs)
+		bind, err := Bind(types, tt.abi, tt.bytecode, tt.fsigs, "bindtest", LangGo, tt.libs, tt.aliases)
 		if err != nil {
 			t.Fatalf("test %d: failed to generate binding: %v", i, err)
 		}
@@ -1835,7 +1901,7 @@ public class Test {
 		},
 	}
 	for i, c := range cases {
-		binding, err := Bind([]string{c.name}, []string{c.abi}, []string{c.bytecode}, nil, "bindtest", LangJava, nil)
+		binding, err := Bind([]string{c.name}, []string{c.abi}, []string{c.bytecode}, nil, "bindtest", LangJava, nil, nil)
 		if err != nil {
 			t.Fatalf("test %d: failed to generate binding: %v", i, err)
 		}
diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go
index 7698115008..659cf1b4c5 100644
--- a/cmd/abigen/main.go
+++ b/cmd/abigen/main.go
@@ -21,6 +21,7 @@ import (
 	"fmt"
 	"io/ioutil"
 	"os"
+	"regexp"
 	"strings"
 
 	"github.com/ethereum/go-ethereum/accounts/abi/bind"
@@ -103,6 +104,10 @@ var (
 		Usage: "Destination language for the bindings (go, java, objc)",
 		Value: "go",
 	}
+	aliasFlag = cli.StringFlag{
+		Name:  "alias",
+		Usage: "Comma separated aliases for function and event renaming, e.g. foo=bar",
+	}
 )
 
 func init() {
@@ -120,6 +125,7 @@ func init() {
 		pkgFlag,
 		outFlag,
 		langFlag,
+		aliasFlag,
 	}
 	app.Action = utils.MigrateFlags(abigen)
 	cli.CommandHelpTemplate = commandHelperTemplate
@@ -144,11 +150,12 @@ func abigen(c *cli.Context) error {
 	}
 	// If the entire solidity code was specified, build and bind based on that
 	var (
-		abis  []string
-		bins  []string
-		types []string
-		sigs  []map[string]string
-		libs  = make(map[string]string)
+		abis    []string
+		bins    []string
+		types   []string
+		sigs    []map[string]string
+		libs    = make(map[string]string)
+		aliases = make(map[string]string)
 	)
 	if c.GlobalString(abiFlag.Name) != "" {
 		// Load up the ABI, optional bytecode and type name from the parameters
@@ -232,8 +239,20 @@ func abigen(c *cli.Context) error {
 			libs[libPattern] = nameParts[len(nameParts)-1]
 		}
 	}
+	// Extract all aliases from the flags
+	if c.GlobalIsSet(aliasFlag.Name) {
+		// We support multi-versions for aliasing
+		// e.g.
+		//      foo=bar,foo2=bar2
+		//      foo:bar,foo2:bar2
+		re := regexp.MustCompile(`(?:(\w+)[:=](\w+))`)
+		submatches := re.FindAllStringSubmatch(c.GlobalString(aliasFlag.Name), -1)
+		for _, match := range submatches {
+			aliases[match[1]] = match[2]
+		}
+	}
 	// Generate the contract binding
-	code, err := bind.Bind(types, abis, bins, sigs, c.GlobalString(pkgFlag.Name), lang, libs)
+	code, err := bind.Bind(types, abis, bins, sigs, c.GlobalString(pkgFlag.Name), lang, libs, aliases)
 	if err != nil {
 		utils.Fatalf("Failed to generate ABI binding: %v", err)
 	}