mobile: initial wrappers for mobile support
This commit is contained in:
		
							
								
								
									
										15
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -62,6 +62,21 @@ matrix: | |||||||
|         - go run build/ci.go install |         - go run build/ci.go install | ||||||
|         - go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -upload gethstore/builds |         - go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -upload gethstore/builds | ||||||
|  |  | ||||||
|  |     # This builder does the mobile builds (and nothing else) | ||||||
|  |     - os: osx | ||||||
|  |       go: 1.7 | ||||||
|  |       script: | ||||||
|  |         - brew update | ||||||
|  |         - brew install android-sdk | ||||||
|  |         - export ANDROID_HOME=/usr/local/opt/android-sdk | ||||||
|  |         - echo "y" | android update sdk --no-ui --filter platform | ||||||
|  |         - go get github.com/tools/godep | ||||||
|  |         - godep restore | ||||||
|  |         - go get golang.org/x/mobile/cmd/gomobile | ||||||
|  |         - gomobile init | ||||||
|  |         - gomobile bind --target=android --javapkg=org.ethereum -v github.com/ethereum/go-ethereum/mobile | ||||||
|  |         - gomobile bind --target=ios --tags=ios -v github.com/ethereum/go-ethereum/mobile | ||||||
|  |  | ||||||
| install: | install: | ||||||
|   - go get golang.org/x/tools/cmd/cover |   - go get golang.org/x/tools/cmd/cover | ||||||
| script: | script: | ||||||
|   | |||||||
| @@ -32,11 +32,20 @@ import ( | |||||||
| 	"golang.org/x/tools/imports" | 	"golang.org/x/tools/imports" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // Lang is a target programming language selector to generate bindings for. | ||||||
|  | type Lang int | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	LangGo Lang = iota | ||||||
|  | 	LangJava | ||||||
|  | 	LangObjC | ||||||
|  | ) | ||||||
|  |  | ||||||
| // Bind generates a Go wrapper around a contract ABI. This wrapper isn't meant | // Bind generates a Go wrapper around a contract ABI. This wrapper isn't meant | ||||||
| // to be used as is in client code, but rather as an intermediate struct which | // 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 | // enforces compile time type safety and naming convention opposed to having to | ||||||
| // manually maintain hard coded strings that break on runtime. | // manually maintain hard coded strings that break on runtime. | ||||||
| func Bind(types []string, abis []string, bytecodes []string, pkg string) (string, error) { | func Bind(types []string, abis []string, bytecodes []string, pkg string, lang Lang) (string, error) { | ||||||
| 	// Process each individual contract requested binding | 	// Process each individual contract requested binding | ||||||
| 	contracts := make(map[string]*tmplContract) | 	contracts := make(map[string]*tmplContract) | ||||||
|  |  | ||||||
| @@ -62,7 +71,7 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string) (string | |||||||
| 		for _, original := range evmABI.Methods { | 		for _, original := range evmABI.Methods { | ||||||
| 			// Normalize the method for capital cases and non-anonymous inputs/outputs | 			// Normalize the method for capital cases and non-anonymous inputs/outputs | ||||||
| 			normalized := original | 			normalized := original | ||||||
| 			normalized.Name = capitalise(original.Name) | 			normalized.Name = methodNormalizer[lang](original.Name) | ||||||
|  |  | ||||||
| 			normalized.Inputs = make([]abi.Argument, len(original.Inputs)) | 			normalized.Inputs = make([]abi.Argument, len(original.Inputs)) | ||||||
| 			copy(normalized.Inputs, original.Inputs) | 			copy(normalized.Inputs, original.Inputs) | ||||||
| @@ -78,7 +87,7 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string) (string | |||||||
| 					normalized.Outputs[j].Name = capitalise(output.Name) | 					normalized.Outputs[j].Name = capitalise(output.Name) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			// Append the methos to the call or transact lists | 			// Append the methods to the call or transact lists | ||||||
| 			if original.Const { | 			if original.Const { | ||||||
| 				calls[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original)} | 				calls[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original)} | ||||||
| 			} else { | 			} else { | ||||||
| @@ -87,7 +96,7 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string) (string | |||||||
| 		} | 		} | ||||||
| 		contracts[types[i]] = &tmplContract{ | 		contracts[types[i]] = &tmplContract{ | ||||||
| 			Type:        capitalise(types[i]), | 			Type:        capitalise(types[i]), | ||||||
| 			InputABI:    strippedABI, | 			InputABI:    strings.Replace(strippedABI, "\"", "\\\"", -1), | ||||||
| 			InputBin:    strings.TrimSpace(bytecodes[i]), | 			InputBin:    strings.TrimSpace(bytecodes[i]), | ||||||
| 			Constructor: evmABI.Constructor, | 			Constructor: evmABI.Constructor, | ||||||
| 			Calls:       calls, | 			Calls:       calls, | ||||||
| @@ -102,9 +111,12 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string) (string | |||||||
| 	buffer := new(bytes.Buffer) | 	buffer := new(bytes.Buffer) | ||||||
|  |  | ||||||
| 	funcs := map[string]interface{}{ | 	funcs := map[string]interface{}{ | ||||||
| 		"bindtype": bindType, | 		"bindtype":     bindType[lang], | ||||||
|  | 		"namedtype":    namedType[lang], | ||||||
|  | 		"capitalise":   capitalise, | ||||||
|  | 		"decapitalise": decapitalise, | ||||||
| 	} | 	} | ||||||
| 	tmpl := template.Must(template.New("").Funcs(funcs).Parse(tmplSource)) | 	tmpl := template.Must(template.New("").Funcs(funcs).Parse(tmplSource[lang])) | ||||||
| 	if err := tmpl.Execute(buffer, data); err != nil { | 	if err := tmpl.Execute(buffer, data); err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| @@ -116,10 +128,17 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string) (string | |||||||
| 	return string(code), nil | 	return string(code), nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // bindType converts a Solidity type to a Go one. Since there is no clear mapping | // bindType is a set of type binders that convert Solidity types to some supported | ||||||
|  | // programming language. | ||||||
|  | var bindType = map[Lang]func(kind abi.Type) string{ | ||||||
|  | 	LangGo:   bindTypeGo, | ||||||
|  | 	LangJava: bindTypeJava, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // bindTypeGo converts a Solidity type to a Go one. Since there is no clear mapping | ||||||
| // from all Solidity types to Go ones (e.g. uint17), those that cannot be exactly | // from all Solidity types to Go ones (e.g. uint17), those that cannot be exactly | ||||||
| // mapped will use an upscaled type (e.g. *big.Int). | // mapped will use an upscaled type (e.g. *big.Int). | ||||||
| func bindType(kind abi.Type) string { | func bindTypeGo(kind abi.Type) string { | ||||||
| 	stringKind := kind.String() | 	stringKind := kind.String() | ||||||
|  |  | ||||||
| 	switch { | 	switch { | ||||||
| @@ -160,11 +179,137 @@ func bindType(kind abi.Type) string { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // bindTypeJava converts a Solidity type to a Java one. Since there is no clear mapping | ||||||
|  | // from all Solidity types to Java ones (e.g. uint17), those that cannot be exactly | ||||||
|  | // mapped will use an upscaled type (e.g. BigDecimal). | ||||||
|  | func bindTypeJava(kind abi.Type) string { | ||||||
|  | 	stringKind := kind.String() | ||||||
|  |  | ||||||
|  | 	switch { | ||||||
|  | 	case strings.HasPrefix(stringKind, "address"): | ||||||
|  | 		parts := regexp.MustCompile("address(\\[[0-9]*\\])?").FindStringSubmatch(stringKind) | ||||||
|  | 		if len(parts) != 2 { | ||||||
|  | 			return stringKind | ||||||
|  | 		} | ||||||
|  | 		if parts[1] == "" { | ||||||
|  | 			return fmt.Sprintf("Address") | ||||||
|  | 		} | ||||||
|  | 		return fmt.Sprintf("Addresses") | ||||||
|  |  | ||||||
|  | 	case strings.HasPrefix(stringKind, "bytes"): | ||||||
|  | 		parts := regexp.MustCompile("bytes([0-9]*)(\\[[0-9]*\\])?").FindStringSubmatch(stringKind) | ||||||
|  | 		if len(parts) != 3 { | ||||||
|  | 			return stringKind | ||||||
|  | 		} | ||||||
|  | 		if parts[2] != "" { | ||||||
|  | 			return "byte[][]" | ||||||
|  | 		} | ||||||
|  | 		return "byte[]" | ||||||
|  |  | ||||||
|  | 	case strings.HasPrefix(stringKind, "int") || strings.HasPrefix(stringKind, "uint"): | ||||||
|  | 		parts := regexp.MustCompile("(u)?int([0-9]*)(\\[[0-9]*\\])?").FindStringSubmatch(stringKind) | ||||||
|  | 		if len(parts) != 4 { | ||||||
|  | 			return stringKind | ||||||
|  | 		} | ||||||
|  | 		switch parts[2] { | ||||||
|  | 		case "8", "16", "32", "64": | ||||||
|  | 			if parts[1] == "" { | ||||||
|  | 				if parts[3] == "" { | ||||||
|  | 					return fmt.Sprintf("int%s", parts[2]) | ||||||
|  | 				} | ||||||
|  | 				return fmt.Sprintf("int%s[]", parts[2]) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if parts[3] == "" { | ||||||
|  | 			return fmt.Sprintf("BigInt") | ||||||
|  | 		} | ||||||
|  | 		return fmt.Sprintf("BigInts") | ||||||
|  |  | ||||||
|  | 	case strings.HasPrefix(stringKind, "bool"): | ||||||
|  | 		parts := regexp.MustCompile("bool(\\[[0-9]*\\])?").FindStringSubmatch(stringKind) | ||||||
|  | 		if len(parts) != 2 { | ||||||
|  | 			return stringKind | ||||||
|  | 		} | ||||||
|  | 		if parts[1] == "" { | ||||||
|  | 			return fmt.Sprintf("bool") | ||||||
|  | 		} | ||||||
|  | 		return fmt.Sprintf("bool[]") | ||||||
|  |  | ||||||
|  | 	case strings.HasPrefix(stringKind, "string"): | ||||||
|  | 		parts := regexp.MustCompile("string(\\[[0-9]*\\])?").FindStringSubmatch(stringKind) | ||||||
|  | 		if len(parts) != 2 { | ||||||
|  | 			return stringKind | ||||||
|  | 		} | ||||||
|  | 		if parts[1] == "" { | ||||||
|  | 			return fmt.Sprintf("String") | ||||||
|  | 		} | ||||||
|  | 		return fmt.Sprintf("String[]") | ||||||
|  |  | ||||||
|  | 	default: | ||||||
|  | 		return stringKind | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // namedType is a set of functions that transform language specific types to | ||||||
|  | // named versions that my be used inside method names. | ||||||
|  | var namedType = map[Lang]func(string, abi.Type) string{ | ||||||
|  | 	LangGo:   func(string, abi.Type) string { panic("this shouldn't be needed") }, | ||||||
|  | 	LangJava: namedTypeJava, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // namedTypeJava converts some primitive data types to named variants that can | ||||||
|  | // be used as parts of method names. | ||||||
|  | func namedTypeJava(javaKind string, solKind abi.Type) string { | ||||||
|  | 	switch javaKind { | ||||||
|  | 	case "byte[]": | ||||||
|  | 		return "Binary" | ||||||
|  | 	case "byte[][]": | ||||||
|  | 		return "Binaries" | ||||||
|  | 	case "string": | ||||||
|  | 		return "String" | ||||||
|  | 	case "string[]": | ||||||
|  | 		return "Strings" | ||||||
|  | 	case "bool": | ||||||
|  | 		return "Bool" | ||||||
|  | 	case "bool[]": | ||||||
|  | 		return "Bools" | ||||||
|  | 	case "BigInt": | ||||||
|  | 		parts := regexp.MustCompile("(u)?int([0-9]*)(\\[[0-9]*\\])?").FindStringSubmatch(solKind.String()) | ||||||
|  | 		if len(parts) != 4 { | ||||||
|  | 			return javaKind | ||||||
|  | 		} | ||||||
|  | 		switch parts[2] { | ||||||
|  | 		case "8", "16", "32", "64": | ||||||
|  | 			if parts[3] == "" { | ||||||
|  | 				return capitalise(fmt.Sprintf("%sint%s", parts[1], parts[2])) | ||||||
|  | 			} | ||||||
|  | 			return capitalise(fmt.Sprintf("%sint%ss", parts[1], parts[2])) | ||||||
|  |  | ||||||
|  | 		default: | ||||||
|  | 			return javaKind | ||||||
|  | 		} | ||||||
|  | 	default: | ||||||
|  | 		return javaKind | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // methodNormalizer is a name transformer that modifies Solidity method names to | ||||||
|  | // conform to target language naming concentions. | ||||||
|  | var methodNormalizer = map[Lang]func(string) string{ | ||||||
|  | 	LangGo:   capitalise, | ||||||
|  | 	LangJava: decapitalise, | ||||||
|  | } | ||||||
|  |  | ||||||
| // capitalise makes the first character of a string upper case. | // capitalise makes the first character of a string upper case. | ||||||
| func capitalise(input string) string { | func capitalise(input string) string { | ||||||
| 	return strings.ToUpper(input[:1]) + input[1:] | 	return strings.ToUpper(input[:1]) + input[1:] | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // decapitalise makes the first character of a string lower case. | ||||||
|  | func decapitalise(input string) string { | ||||||
|  | 	return strings.ToLower(input[:1]) + input[1:] | ||||||
|  | } | ||||||
|  |  | ||||||
| // structured checks whether a method has enough information to return a proper | // structured checks whether a method has enough information to return a proper | ||||||
| // Go struct ot if flat returns are needed. | // Go struct ot if flat returns are needed. | ||||||
| func structured(method abi.Method) bool { | func structured(method abi.Method) bool { | ||||||
|   | |||||||
| @@ -398,7 +398,7 @@ func TestBindings(t *testing.T) { | |||||||
| 	// Generate the test suite for all the contracts | 	// Generate the test suite for all the contracts | ||||||
| 	for i, tt := range bindTests { | 	for i, tt := range bindTests { | ||||||
| 		// Generate the binding and create a Go source file in the workspace | 		// Generate the binding and create a Go source file in the workspace | ||||||
| 		bind, err := Bind([]string{tt.name}, []string{tt.abi}, []string{tt.bytecode}, "bindtest") | 		bind, err := Bind([]string{tt.name}, []string{tt.abi}, []string{tt.bytecode}, "bindtest", LangGo) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			t.Fatalf("test %d: failed to generate binding: %v", i, err) | 			t.Fatalf("test %d: failed to generate binding: %v", i, err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -42,9 +42,16 @@ type tmplMethod struct { | |||||||
| 	Structured bool       // Whether the returns should be accumulated into a contract | 	Structured bool       // Whether the returns should be accumulated into a contract | ||||||
| } | } | ||||||
|  |  | ||||||
| // tmplSource is the Go source template use to generate the contract binding | // tmplSource is language to template mapping containing all the supported | ||||||
|  | // programming languages the package can generate to. | ||||||
|  | var tmplSource = map[Lang]string{ | ||||||
|  | 	LangGo:   tmplSourceGo, | ||||||
|  | 	LangJava: tmplSourceJava, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // tmplSourceGo is the Go source template use to generate the contract binding | ||||||
| // based on. | // based on. | ||||||
| const tmplSource = ` | const tmplSourceGo = ` | ||||||
| // This file is an automatically generated Go binding. Do not modify as any | // This file is an automatically generated Go binding. Do not modify as any | ||||||
| // change will likely be lost upon the next re-generation! | // change will likely be lost upon the next re-generation! | ||||||
|  |  | ||||||
| @@ -52,7 +59,7 @@ package {{.Package}} | |||||||
|  |  | ||||||
| {{range $contract := .Contracts}} | {{range $contract := .Contracts}} | ||||||
| 	// {{.Type}}ABI is the input ABI used to generate the binding from. | 	// {{.Type}}ABI is the input ABI used to generate the binding from. | ||||||
| 	const {{.Type}}ABI = ` + "`" + `{{.InputABI}}` + "`" + ` | 	const {{.Type}}ABI = "{{.InputABI}}" | ||||||
|  |  | ||||||
| 	{{if .InputBin}} | 	{{if .InputBin}} | ||||||
| 		// {{.Type}}Bin is the compiled bytecode used for deploying new contracts. | 		// {{.Type}}Bin is the compiled bytecode used for deploying new contracts. | ||||||
| @@ -258,3 +265,105 @@ package {{.Package}} | |||||||
| 	{{end}} | 	{{end}} | ||||||
| {{end}} | {{end}} | ||||||
| ` | ` | ||||||
|  |  | ||||||
|  | // tmplSourceJava is the Java source template use to generate the contract binding | ||||||
|  | // based on. | ||||||
|  | const tmplSourceJava = ` | ||||||
|  | // This file is an automatically generated Java binding. Do not modify as any | ||||||
|  | // change will likely be lost upon the next re-generation! | ||||||
|  |  | ||||||
|  | package {{.Package}}; | ||||||
|  |  | ||||||
|  | import org.ethereum.geth.*; | ||||||
|  | import org.ethereum.geth.internal.*; | ||||||
|  |  | ||||||
|  | {{range $contract := .Contracts}} | ||||||
|  | 	public class {{.Type}} { | ||||||
|  | 		// ABI is the input ABI used to generate the binding from. | ||||||
|  | 		public final static String ABI = "{{.InputABI}}"; | ||||||
|  |  | ||||||
|  | 		{{if .InputBin}} | ||||||
|  | 			// Bytecode is the compiled bytecode used for deploying new contracts. | ||||||
|  | 			public final static byte[] Bytecode = "{{.InputBin}}".getBytes(); | ||||||
|  |  | ||||||
|  | 			// deploy deploys a new Ethereum contract, binding an instance of {{.Type}} to it. | ||||||
|  | 			public static {{.Type}} deploy(TransactOpts auth, EthereumClient client{{range .Constructor.Inputs}}, {{bindtype .Type}} {{.Name}}{{end}}) throws Exception { | ||||||
|  | 				Interfaces args = Geth.newInterfaces({{(len .Constructor.Inputs)}}); | ||||||
|  | 				{{range $index, $element := .Constructor.Inputs}} | ||||||
|  | 				  args.set({{$index}}, Geth.newInterface()); args.get({{$index}}).set{{namedtype (bindtype .Type) .Type}}({{.Name}}); | ||||||
|  | 				{{end}} | ||||||
|  | 				return new {{.Type}}(Geth.deployContract(auth, ABI, Bytecode, client, args)); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// Internal constructor used by contract deployment. | ||||||
|  | 			private {{.Type}}(BoundContract deployment) { | ||||||
|  | 				this.Address  = deployment.getAddress(); | ||||||
|  | 				this.Deployer = deployment.getDeployer(); | ||||||
|  | 				this.Contract = deployment; | ||||||
|  | 			} | ||||||
|  | 		{{end}} | ||||||
|  |  | ||||||
|  | 		// Ethereum address where this contract is located at. | ||||||
|  | 		public final Address Address; | ||||||
|  |  | ||||||
|  | 		// Ethereum transaction in which this contract was deployed (if known!). | ||||||
|  | 		public final Transaction Deployer; | ||||||
|  |  | ||||||
|  | 		// Contract instance bound to a blockchain address. | ||||||
|  | 		private final BoundContract Contract; | ||||||
|  |  | ||||||
|  | 		// Creates a new instance of {{.Type}}, bound to a specific deployed contract. | ||||||
|  | 		public {{.Type}}(Address address, EthereumClient client) throws Exception { | ||||||
|  | 			this(Geth.bindContract(address, ABI, client)); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		{{range .Calls}} | ||||||
|  | 			{{if gt (len .Normalized.Outputs) 1}} | ||||||
|  | 			// {{capitalise .Normalized.Name}}Results is the output of a call to {{.Normalized.Name}}. | ||||||
|  | 			public class {{capitalise .Normalized.Name}}Results { | ||||||
|  | 				{{range $index, $item := .Normalized.Outputs}}public {{bindtype .Type}} {{if ne .Name ""}}{{.Name}}{{else}}Return{{$index}}{{end}}; | ||||||
|  | 				{{end}} | ||||||
|  | 			} | ||||||
|  | 			{{end}} | ||||||
|  |  | ||||||
|  | 			// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.Id}}. | ||||||
|  | 			// | ||||||
|  | 			// Solidity: {{.Original.String}} | ||||||
|  | 			public {{if gt (len .Normalized.Outputs) 1}}{{capitalise .Normalized.Name}}Results{{else}}{{range .Normalized.Outputs}}{{bindtype .Type}}{{end}}{{end}} {{.Normalized.Name}}(CallOpts opts{{range .Normalized.Inputs}}, {{bindtype .Type}} {{.Name}}{{end}}) throws Exception { | ||||||
|  | 				Interfaces args = Geth.newInterfaces({{(len .Normalized.Inputs)}}); | ||||||
|  | 				{{range $index, $item := .Normalized.Inputs}}args.set({{$index}}, Geth.newInterface()); args.get({{$index}}).set{{namedtype (bindtype .Type) .Type}}({{.Name}}); | ||||||
|  | 				{{end}} | ||||||
|  |  | ||||||
|  | 				Interfaces results = Geth.newInterfaces({{(len .Normalized.Outputs)}}); | ||||||
|  | 				{{range $index, $item := .Normalized.Outputs}}Interface result{{$index}} = Geth.newInterface(); result{{$index}}.setDefault{{namedtype (bindtype .Type) .Type}}(); results.set({{$index}}, result{{$index}}); | ||||||
|  | 				{{end}} | ||||||
|  |  | ||||||
|  | 				if (opts == null) { | ||||||
|  | 					opts = Geth.newCallOpts(); | ||||||
|  | 				} | ||||||
|  | 				this.Contract.call(opts, results, "{{.Original.Name}}", args); | ||||||
|  | 				{{if gt (len .Normalized.Outputs) 1}} | ||||||
|  | 					{{capitalise .Normalized.Name}}Results result = new {{capitalise .Normalized.Name}}Results(); | ||||||
|  | 					{{range $index, $item := .Normalized.Outputs}}result.{{if ne .Name ""}}{{.Name}}{{else}}Return{{$index}}{{end}} = results.get({{$index}}).get{{namedtype (bindtype .Type) .Type}}(); | ||||||
|  | 					{{end}} | ||||||
|  | 					return result; | ||||||
|  | 				{{else}}{{range .Normalized.Outputs}}return results.get(0).get{{namedtype (bindtype .Type) .Type}}();{{end}} | ||||||
|  | 				{{end}} | ||||||
|  | 			} | ||||||
|  | 		{{end}} | ||||||
|  |  | ||||||
|  | 		{{range .Transacts}} | ||||||
|  | 			// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.Id}}. | ||||||
|  | 			// | ||||||
|  | 			// Solidity: {{.Original.String}} | ||||||
|  | 			public Transaction {{.Normalized.Name}}(TransactOpts opts{{range .Normalized.Inputs}}, {{bindtype .Type}} {{.Name}}{{end}}) throws Exception { | ||||||
|  | 				Interfaces args = Geth.newInterfaces({{(len .Normalized.Inputs)}}); | ||||||
|  | 				{{range $index, $item := .Normalized.Inputs}}args.set({{$index}}, Geth.newInterface()); args.get({{$index}}).set{{namedtype (bindtype .Type) .Type}}({{.Name}}); | ||||||
|  | 				{{end}} | ||||||
|  |  | ||||||
|  | 				return this.Contract.transact(opts, "{{.Original.Name}}"	, args); | ||||||
|  | 			} | ||||||
|  | 		{{end}} | ||||||
|  | 	} | ||||||
|  | {{end}} | ||||||
|  | ` | ||||||
|   | |||||||
| @@ -46,12 +46,20 @@ import ( | |||||||
| const ( | const ( | ||||||
| 	keyHeaderKDF = "scrypt" | 	keyHeaderKDF = "scrypt" | ||||||
|  |  | ||||||
| 	// n,r,p = 2^18, 8, 1 uses 256MB memory and approx 1s CPU time on a modern CPU. | 	// StandardScryptN is the N parameter of Scrypt encryption algorithm, using 256MB | ||||||
|  | 	// memory and taking approximately 1s CPU time on a modern processor. | ||||||
| 	StandardScryptN = 1 << 18 | 	StandardScryptN = 1 << 18 | ||||||
|  |  | ||||||
|  | 	// StandardScryptP is the P parameter of Scrypt encryption algorithm, using 256MB | ||||||
|  | 	// memory and taking approximately 1s CPU time on a modern processor. | ||||||
| 	StandardScryptP = 1 | 	StandardScryptP = 1 | ||||||
|  |  | ||||||
| 	// n,r,p = 2^12, 8, 6 uses 4MB memory and approx 100ms CPU time on a modern CPU. | 	// LightScryptN is the N parameter of Scrypt encryption algorithm, using 4MB | ||||||
|  | 	// memory and taking approximately 100ms CPU time on a modern processor. | ||||||
| 	LightScryptN = 1 << 12 | 	LightScryptN = 1 << 12 | ||||||
|  |  | ||||||
|  | 	// LightScryptP is the P parameter of Scrypt encryption algorithm, using 4MB | ||||||
|  | 	// memory and taking approximately 100ms CPU time on a modern processor. | ||||||
| 	LightScryptP = 6 | 	LightScryptP = 6 | ||||||
|  |  | ||||||
| 	scryptR     = 8 | 	scryptR     = 8 | ||||||
|   | |||||||
| @@ -31,14 +31,15 @@ import ( | |||||||
| var ( | var ( | ||||||
| 	abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind") | 	abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind") | ||||||
| 	binFlag = flag.String("bin", "", "Path to the Ethereum contract bytecode (generate deploy method)") | 	binFlag = flag.String("bin", "", "Path to the Ethereum contract bytecode (generate deploy method)") | ||||||
| 	typFlag = flag.String("type", "", "Go struct name for the binding (default = package name)") | 	typFlag = flag.String("type", "", "Struct name for the binding (default = package name)") | ||||||
|  |  | ||||||
| 	solFlag  = flag.String("sol", "", "Path to the Ethereum contract Solidity source to build and bind") | 	solFlag  = flag.String("sol", "", "Path to the Ethereum contract Solidity source to build and bind") | ||||||
| 	solcFlag = flag.String("solc", "solc", "Solidity compiler to use if source builds are requested") | 	solcFlag = flag.String("solc", "solc", "Solidity compiler to use if source builds are requested") | ||||||
| 	excFlag  = flag.String("exc", "", "Comma separated types to exclude from binding") | 	excFlag  = flag.String("exc", "", "Comma separated types to exclude from binding") | ||||||
|  |  | ||||||
| 	pkgFlag = flag.String("pkg", "", "Go package name to generate the binding into") | 	pkgFlag  = flag.String("pkg", "", "Package name to generate the binding into") | ||||||
| 	outFlag = flag.String("out", "", "Output file for the generated binding (default = stdout)") | 	outFlag  = flag.String("out", "", "Output file for the generated binding (default = stdout)") | ||||||
|  | 	langFlag = flag.String("lang", "go", "Destination language for the bindings (go, java, objc)") | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func main() { | func main() { | ||||||
| @@ -53,7 +54,19 @@ func main() { | |||||||
| 		os.Exit(-1) | 		os.Exit(-1) | ||||||
| 	} | 	} | ||||||
| 	if *pkgFlag == "" { | 	if *pkgFlag == "" { | ||||||
| 		fmt.Printf("No destination Go package specified (--pkg)\n") | 		fmt.Printf("No destination package specified (--pkg)\n") | ||||||
|  | 		os.Exit(-1) | ||||||
|  | 	} | ||||||
|  | 	var lang bind.Lang | ||||||
|  | 	switch *langFlag { | ||||||
|  | 	case "go": | ||||||
|  | 		lang = bind.LangGo | ||||||
|  | 	case "java": | ||||||
|  | 		lang = bind.LangJava | ||||||
|  | 	case "objc": | ||||||
|  | 		lang = bind.LangObjC | ||||||
|  | 	default: | ||||||
|  | 		fmt.Printf("Unsupported destination language \"%s\" (--lang)\n", *langFlag) | ||||||
| 		os.Exit(-1) | 		os.Exit(-1) | ||||||
| 	} | 	} | ||||||
| 	// If the entire solidity code was specified, build and bind based on that | 	// If the entire solidity code was specified, build and bind based on that | ||||||
| @@ -108,7 +121,7 @@ func main() { | |||||||
| 		types = append(types, kind) | 		types = append(types, kind) | ||||||
| 	} | 	} | ||||||
| 	// Generate the contract binding | 	// Generate the contract binding | ||||||
| 	code, err := bind.Bind(types, abis, bins, *pkgFlag) | 	code, err := bind.Bind(types, abis, bins, *pkgFlag, lang) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		fmt.Printf("Failed to generate ABI binding: %v\n", err) | 		fmt.Printf("Failed to generate ABI binding: %v\n", err) | ||||||
| 		os.Exit(-1) | 		os.Exit(-1) | ||||||
|   | |||||||
| @@ -16,11 +16,15 @@ | |||||||
|  |  | ||||||
| package utils | package utils | ||||||
|  |  | ||||||
| import "github.com/ethereum/go-ethereum/p2p/discover" | import ( | ||||||
|  | 	"github.com/ethereum/go-ethereum/core" | ||||||
|  | 	"github.com/ethereum/go-ethereum/p2p/discover" | ||||||
|  | 	"github.com/ethereum/go-ethereum/params" | ||||||
|  | ) | ||||||
|  |  | ||||||
| // FrontierBootNodes are the enode URLs of the P2P bootstrap nodes running on | // MainnetBootnodes are the enode URLs of the P2P bootstrap nodes running on | ||||||
| // the Frontier network. | // the main Ethereum network. | ||||||
| var FrontierBootNodes = []*discover.Node{ | var MainnetBootnodes = []*discover.Node{ | ||||||
| 	// ETH/DEV Go Bootnodes | 	// ETH/DEV Go Bootnodes | ||||||
| 	discover.MustParseNode("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303"), // IE | 	discover.MustParseNode("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303"), // IE | ||||||
| 	discover.MustParseNode("enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303"),  // BR | 	discover.MustParseNode("enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303"),  // BR | ||||||
| @@ -30,12 +34,26 @@ var FrontierBootNodes = []*discover.Node{ | |||||||
| 	discover.MustParseNode("enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303"), | 	discover.MustParseNode("enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303"), | ||||||
| } | } | ||||||
|  |  | ||||||
| // TestNetBootNodes are the enode URLs of the P2P bootstrap nodes running on the | // TestnetBootnodes are the enode URLs of the P2P bootstrap nodes running on the | ||||||
| // Morden test network. | // Morden test network. | ||||||
| var TestNetBootNodes = []*discover.Node{ | var TestnetBootnodes = []*discover.Node{ | ||||||
| 	// ETH/DEV Go Bootnodes | 	// ETH/DEV Go Bootnodes | ||||||
| 	discover.MustParseNode("enode://e4533109cc9bd7604e4ff6c095f7a1d807e15b38e9bfeb05d3b7c423ba86af0a9e89abbf40bd9dde4250fef114cd09270fa4e224cbeef8b7bf05a51e8260d6b8@94.242.229.4:40404"), | 	discover.MustParseNode("enode://e4533109cc9bd7604e4ff6c095f7a1d807e15b38e9bfeb05d3b7c423ba86af0a9e89abbf40bd9dde4250fef114cd09270fa4e224cbeef8b7bf05a51e8260d6b8@94.242.229.4:40404"), | ||||||
| 	discover.MustParseNode("enode://8c336ee6f03e99613ad21274f269479bf4413fb294d697ef15ab897598afb931f56beb8e97af530aee20ce2bcba5776f4a312bc168545de4d43736992c814592@94.242.229.203:30303"), | 	discover.MustParseNode("enode://8c336ee6f03e99613ad21274f269479bf4413fb294d697ef15ab897598afb931f56beb8e97af530aee20ce2bcba5776f4a312bc168545de4d43736992c814592@94.242.229.203:30303"), | ||||||
|  |  | ||||||
| 	// ETH/DEV Cpp Bootnodes | 	// ETH/DEV Cpp Bootnodes | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // MainnetChainConfig is the chain parameters to run a node on the main network. | ||||||
|  | var MainnetChainConfig = &core.ChainConfig{ | ||||||
|  | 	HomesteadBlock: params.MainNetHomesteadBlock, | ||||||
|  | 	DAOForkBlock:   params.MainNetDAOForkBlock, | ||||||
|  | 	DAOForkSupport: true, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TestnetChainConfig is the chain parameters to run a node on the test network. | ||||||
|  | var TestnetChainConfig = &core.ChainConfig{ | ||||||
|  | 	HomesteadBlock: params.TestNetHomesteadBlock, | ||||||
|  | 	DAOForkBlock:   params.TestNetDAOForkBlock, | ||||||
|  | 	DAOForkSupport: false, | ||||||
|  | } | ||||||
|   | |||||||
| @@ -487,9 +487,9 @@ func MakeBootstrapNodes(ctx *cli.Context) []*discover.Node { | |||||||
| 	// Return pre-configured nodes if none were manually requested | 	// Return pre-configured nodes if none were manually requested | ||||||
| 	if !ctx.GlobalIsSet(BootnodesFlag.Name) { | 	if !ctx.GlobalIsSet(BootnodesFlag.Name) { | ||||||
| 		if ctx.GlobalBool(TestNetFlag.Name) { | 		if ctx.GlobalBool(TestNetFlag.Name) { | ||||||
| 			return TestNetBootNodes | 			return TestnetBootnodes | ||||||
| 		} | 		} | ||||||
| 		return FrontierBootNodes | 		return MainnetBootnodes | ||||||
| 	} | 	} | ||||||
| 	// Otherwise parse and use the CLI bootstrap nodes | 	// Otherwise parse and use the CLI bootstrap nodes | ||||||
| 	bootnodes := []*discover.Node{} | 	bootnodes := []*discover.Node{} | ||||||
|   | |||||||
| @@ -35,7 +35,10 @@ const ( | |||||||
| var hashJsonLengthErr = errors.New("common: unmarshalJSON failed: hash must be exactly 32 bytes") | var hashJsonLengthErr = errors.New("common: unmarshalJSON failed: hash must be exactly 32 bytes") | ||||||
|  |  | ||||||
| type ( | type ( | ||||||
| 	Hash    [HashLength]byte | 	// Hash represents the 32 byte Keccak256 hash of arbitrary data. | ||||||
|  | 	Hash [HashLength]byte | ||||||
|  |  | ||||||
|  | 	// Address represents the 20 byte address of an Ethereum account. | ||||||
| 	Address [AddressLength]byte | 	Address [AddressLength]byte | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -79,7 +79,7 @@ func (n *BlockNonce) UnmarshalJSON(input []byte) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // Header represents Ethereum block headers. | // Header represents a block header in the Ethereum blockchain. | ||||||
| type Header struct { | type Header struct { | ||||||
| 	ParentHash  common.Hash    // Hash to the previous block | 	ParentHash  common.Hash    // Hash to the previous block | ||||||
| 	UncleHash   common.Hash    // Uncles of this block | 	UncleHash   common.Hash    // Uncles of this block | ||||||
| @@ -214,7 +214,7 @@ type Body struct { | |||||||
| 	Uncles       []*Header | 	Uncles       []*Header | ||||||
| } | } | ||||||
|  |  | ||||||
| // Block represents a block in the Ethereum blockchain. | // Block represents an entire block in the Ethereum blockchain. | ||||||
| type Block struct { | type Block struct { | ||||||
| 	header       *Header | 	header       *Header | ||||||
| 	uncles       []*Header | 	uncles       []*Header | ||||||
|   | |||||||
							
								
								
									
										181
									
								
								mobile/accounts.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								mobile/accounts.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains all the wrappers from the accounts package to support client side key | ||||||
|  | // management on mobile platforms. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/ethereum/go-ethereum/accounts" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	// StandardScryptN is the N parameter of Scrypt encryption algorithm, using 256MB | ||||||
|  | 	// memory and taking approximately 1s CPU time on a modern processor. | ||||||
|  | 	StandardScryptN = int(accounts.StandardScryptN) | ||||||
|  |  | ||||||
|  | 	// StandardScryptP is the P parameter of Scrypt encryption algorithm, using 256MB | ||||||
|  | 	// memory and taking approximately 1s CPU time on a modern processor. | ||||||
|  | 	StandardScryptP = int(accounts.StandardScryptP) | ||||||
|  |  | ||||||
|  | 	// LightScryptN is the N parameter of Scrypt encryption algorithm, using 4MB | ||||||
|  | 	// memory and taking approximately 100ms CPU time on a modern processor. | ||||||
|  | 	LightScryptN = int(accounts.LightScryptN) | ||||||
|  |  | ||||||
|  | 	// LightScryptP is the P parameter of Scrypt encryption algorithm, using 4MB | ||||||
|  | 	// memory and taking approximately 100ms CPU time on a modern processor. | ||||||
|  | 	LightScryptP = int(accounts.LightScryptP) | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Account represents a stored key. | ||||||
|  | type Account struct{ account accounts.Account } | ||||||
|  |  | ||||||
|  | // Accounts represents a slice of accounts. | ||||||
|  | type Accounts struct{ accounts []accounts.Account } | ||||||
|  |  | ||||||
|  | // Size returns the number of accounts in the slice. | ||||||
|  | func (a *Accounts) Size() int { | ||||||
|  | 	return len(a.accounts) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the account at the given index from the slice. | ||||||
|  | func (a *Accounts) Get(index int) (*Account, error) { | ||||||
|  | 	if index < 0 || index >= len(a.accounts) { | ||||||
|  | 		return nil, errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	return &Account{a.accounts[index]}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Set sets the account at the given index in the slice. | ||||||
|  | func (a *Accounts) Set(index int, account *Account) error { | ||||||
|  | 	if index < 0 || index >= len(a.accounts) { | ||||||
|  | 		return errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	a.accounts[index] = account.account | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetAddress retrieves the address associated with the account. | ||||||
|  | func (a *Account) GetAddress() *Address { | ||||||
|  | 	return &Address{a.account.Address} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetFile retrieves the path of the file containing the account key. | ||||||
|  | func (a *Account) GetFile() string { | ||||||
|  | 	return a.account.File | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // AccountManager manages a key storage directory on disk. | ||||||
|  | type AccountManager struct{ manager *accounts.Manager } | ||||||
|  |  | ||||||
|  | // NewAccountManager creates a manager for the given directory. | ||||||
|  | func NewAccountManager(keydir string, scryptN, scryptP int) *AccountManager { | ||||||
|  | 	return &AccountManager{manager: accounts.NewManager(keydir, scryptN, scryptP)} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // HasAddress reports whether a key with the given address is present. | ||||||
|  | func (am *AccountManager) HasAddress(addr *Address) bool { | ||||||
|  | 	return am.manager.HasAddress(addr.address) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetAccounts returns all key files present in the directory. | ||||||
|  | func (am *AccountManager) GetAccounts() *Accounts { | ||||||
|  | 	return &Accounts{am.manager.Accounts()} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // DeleteAccount deletes the key matched by account if the passphrase is correct. | ||||||
|  | // If a contains no filename, the address must match a unique key. | ||||||
|  | func (am *AccountManager) DeleteAccount(a *Account, passphrase string) error { | ||||||
|  | 	return am.manager.DeleteAccount(accounts.Account{ | ||||||
|  | 		Address: a.account.Address, | ||||||
|  | 		File:    a.account.File, | ||||||
|  | 	}, passphrase) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Sign signs hash with an unlocked private key matching the given address. | ||||||
|  | func (am *AccountManager) Sign(addr *Address, hash []byte) ([]byte, error) { | ||||||
|  | 	return am.manager.Sign(addr.address, hash) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SignWithPassphrase signs hash if the private key matching the given address can be | ||||||
|  | // decrypted with the given passphrase. | ||||||
|  | func (am *AccountManager) SignWithPassphrase(addr *Address, passphrase string, hash []byte) ([]byte, error) { | ||||||
|  | 	return am.manager.SignWithPassphrase(addr.address, passphrase, hash) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Unlock unlocks the given account indefinitely. | ||||||
|  | func (am *AccountManager) Unlock(a *Account, passphrase string) error { | ||||||
|  | 	return am.manager.TimedUnlock(a.account, passphrase, 0) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Lock removes the private key with the given address from memory. | ||||||
|  | func (am *AccountManager) Lock(addr *Address) error { | ||||||
|  | 	return am.manager.Lock(addr.address) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TimedUnlock unlocks the given account with the passphrase. The account | ||||||
|  | // stays unlocked for the duration of timeout. A timeout of 0 unlocks the account | ||||||
|  | // until the program exits. The account must match a unique key file. | ||||||
|  | // | ||||||
|  | // If the account address is already unlocked for a duration, TimedUnlock extends or | ||||||
|  | // shortens the active unlock timeout. If the address was previously unlocked | ||||||
|  | // indefinitely the timeout is not altered. | ||||||
|  | func (am *AccountManager) TimedUnlock(a *Account, passphrase string, timeout int64) error { | ||||||
|  | 	return am.manager.TimedUnlock(a.account, passphrase, time.Duration(timeout)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewAccount generates a new key and stores it into the key directory, | ||||||
|  | // encrypting it with the passphrase. | ||||||
|  | func (am *AccountManager) NewAccount(passphrase string) (*Account, error) { | ||||||
|  | 	account, err := am.manager.NewAccount(passphrase) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return &Account{account}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ExportKey exports as a JSON key, encrypted with newPassphrase. | ||||||
|  | func (am *AccountManager) ExportKey(a *Account, passphrase, newPassphrase string) ([]byte, error) { | ||||||
|  | 	return am.manager.Export(a.account, passphrase, newPassphrase) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ImportKey stores the given encrypted JSON key into the key directory. | ||||||
|  | func (am *AccountManager) ImportKey(keyJSON []byte, passphrase, newPassphrase string) (*Account, error) { | ||||||
|  | 	account, err := am.manager.Import(keyJSON, passphrase, newPassphrase) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return &Account{account}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Update changes the passphrase of an existing account. | ||||||
|  | func (am *AccountManager) Update(a *Account, passphrase, newPassphrase string) error { | ||||||
|  | 	return am.manager.Update(a.account, passphrase, newPassphrase) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ImportPreSaleKey decrypts the given Ethereum presale wallet and stores | ||||||
|  | // a key file in the key directory. The key file is encrypted with the same passphrase. | ||||||
|  | func (am *AccountManager) ImportPreSaleKey(keyJSON []byte, passphrase string) (*Account, error) { | ||||||
|  | 	account, err := am.manager.ImportPreSaleKey(keyJSON, passphrase) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return &Account{account}, nil | ||||||
|  | } | ||||||
							
								
								
									
										95
									
								
								mobile/big.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								mobile/big.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains all the wrappers from the math/big package. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"math/big" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // A BigInt represents a signed multi-precision integer. | ||||||
|  | type BigInt struct { | ||||||
|  | 	bigint *big.Int | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewBigInt allocates and returns a new BigInt set to x. | ||||||
|  | func NewBigInt(x int64) *BigInt { | ||||||
|  | 	return &BigInt{big.NewInt(x)} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetBytes returns the absolute value of x as a big-endian byte slice. | ||||||
|  | func (bi *BigInt) GetBytes() []byte { | ||||||
|  | 	return bi.bigint.Bytes() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns the value of x as a formatted decimal string. | ||||||
|  | func (bi *BigInt) String() string { | ||||||
|  | 	return bi.bigint.String() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetInt64 returns the int64 representation of x. If x cannot be represented in | ||||||
|  | // an int64, the result is undefined. | ||||||
|  | func (bi *BigInt) GetInt64() int64 { | ||||||
|  | 	return bi.bigint.Int64() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetBytes interprets buf as the bytes of a big-endian unsigned integer and sets | ||||||
|  | // the big int to that value. | ||||||
|  | func (bi *BigInt) SetBytes(buf []byte) { | ||||||
|  | 	bi.bigint.SetBytes(buf) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetInt64 sets the big int to x. | ||||||
|  | func (bi *BigInt) SetInt64(x int64) { | ||||||
|  | 	bi.bigint.SetInt64(x) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetString sets the big int to x. | ||||||
|  | // | ||||||
|  | // The string prefix determines the actual conversion base. A prefix of "0x" or | ||||||
|  | // "0X" selects base 16; the "0" prefix selects base 8, and a "0b" or "0B" prefix | ||||||
|  | // selects base 2. Otherwise the selected base is 10. | ||||||
|  | func (bi *BigInt) SetString(x string, base int) { | ||||||
|  | 	bi.bigint.SetString(x, base) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // BigInts represents a slice of big ints. | ||||||
|  | type BigInts struct{ bigints []*big.Int } | ||||||
|  |  | ||||||
|  | // Size returns the number of big ints in the slice. | ||||||
|  | func (bi *BigInts) Size() int { | ||||||
|  | 	return len(bi.bigints) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the bigint at the given index from the slice. | ||||||
|  | func (bi *BigInts) Get(index int) (*BigInt, error) { | ||||||
|  | 	if index < 0 || index >= len(bi.bigints) { | ||||||
|  | 		return nil, errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	return &BigInt{bi.bigints[index]}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Set sets the big int at the given index in the slice. | ||||||
|  | func (bi *BigInts) Set(index int, bigint *BigInt) error { | ||||||
|  | 	if index < 0 || index >= len(bi.bigints) { | ||||||
|  | 		return errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	bi.bigints[index] = bigint.bigint | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								mobile/big_go1.7.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								mobile/big_go1.7.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains the wrappers from the math/big package that require Go 1.7 and above. | ||||||
|  |  | ||||||
|  | // +build go1.7 | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | // GetString returns the value of x as a formatted string in some number base. | ||||||
|  | func (bi *BigInt) GetString(base int) string { | ||||||
|  | 	return bi.bigint.Text(base) | ||||||
|  | } | ||||||
							
								
								
									
										202
									
								
								mobile/bind.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								mobile/bind.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,202 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains all the wrappers from the bind package. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"math/big" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
|  | 	"github.com/ethereum/go-ethereum/accounts/abi" | ||||||
|  | 	"github.com/ethereum/go-ethereum/accounts/abi/bind" | ||||||
|  | 	"github.com/ethereum/go-ethereum/common" | ||||||
|  | 	"github.com/ethereum/go-ethereum/core/types" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Signer is an interaface defining the callback when a contract requires a | ||||||
|  | // method to sign the transaction before submission. | ||||||
|  | type Signer interface { | ||||||
|  | 	Sign(*Address, *Transaction) (*Transaction, error) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type signer struct { | ||||||
|  | 	sign bind.SignerFn | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *signer) Sign(addr *Address, tx *Transaction) (*Transaction, error) { | ||||||
|  | 	sig, err := s.sign(addr.address, tx.tx) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return &Transaction{sig}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // CallOpts is the collection of options to fine tune a contract call request. | ||||||
|  | type CallOpts struct { | ||||||
|  | 	opts bind.CallOpts | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewCallOpts creates a new option set for contract calls. | ||||||
|  | func NewCallOpts() *CallOpts { | ||||||
|  | 	return new(CallOpts) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (opts *CallOpts) IsPending() bool    { return opts.opts.Pending } | ||||||
|  | func (opts *CallOpts) GetGasLimit() int64 { return 0 /* TODO(karalabe) */ } | ||||||
|  |  | ||||||
|  | // GetContext cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876) | ||||||
|  | // Even then it's awkward to unpack the subtleties of a Go context out to Java. | ||||||
|  | // func (opts *CallOpts) GetContext() *Context { return &Context{opts.opts.Context} } | ||||||
|  |  | ||||||
|  | func (opts *CallOpts) SetPending(pending bool)     { opts.opts.Pending = pending } | ||||||
|  | func (opts *CallOpts) SetGasLimit(limit int64)     { /* TODO(karalabe) */ } | ||||||
|  | func (opts *CallOpts) SetContext(context *Context) { opts.opts.Context = context.context } | ||||||
|  |  | ||||||
|  | // TransactOpts is the collection of authorization data required to create a | ||||||
|  | // valid Ethereum transaction. | ||||||
|  | type TransactOpts struct { | ||||||
|  | 	opts bind.TransactOpts | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (opts *TransactOpts) GetFrom() *Address    { return &Address{opts.opts.From} } | ||||||
|  | func (opts *TransactOpts) GetNonce() int64      { return opts.opts.Nonce.Int64() } | ||||||
|  | func (opts *TransactOpts) GetValue() *BigInt    { return &BigInt{opts.opts.Value} } | ||||||
|  | func (opts *TransactOpts) GetGasPrice() *BigInt { return &BigInt{opts.opts.GasPrice} } | ||||||
|  | func (opts *TransactOpts) GetGasLimit() int64   { return opts.opts.GasLimit.Int64() } | ||||||
|  |  | ||||||
|  | // GetSigner cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876) | ||||||
|  | // func (opts *TransactOpts) GetSigner() Signer { return &signer{opts.opts.Signer} } | ||||||
|  |  | ||||||
|  | // GetContext cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876) | ||||||
|  | // Even then it's awkward to unpack the subtleties of a Go context out to Java. | ||||||
|  | //func (opts *TransactOpts) GetContext() *Context { return &Context{opts.opts.Context} } | ||||||
|  |  | ||||||
|  | func (opts *TransactOpts) SetFrom(from *Address) { opts.opts.From = from.address } | ||||||
|  | func (opts *TransactOpts) SetNonce(nonce int64)  { opts.opts.Nonce = big.NewInt(nonce) } | ||||||
|  | func (opts *TransactOpts) SetSigner(s Signer) { | ||||||
|  | 	opts.opts.Signer = func(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { | ||||||
|  | 		sig, err := s.Sign(&Address{addr}, &Transaction{tx}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		return sig.tx, nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | func (opts *TransactOpts) SetValue(value *BigInt)      { opts.opts.Value = value.bigint } | ||||||
|  | func (opts *TransactOpts) SetGasPrice(price *BigInt)   { opts.opts.GasPrice = price.bigint } | ||||||
|  | func (opts *TransactOpts) SetGasLimit(limit int64)     { opts.opts.GasLimit = big.NewInt(limit) } | ||||||
|  | func (opts *TransactOpts) SetContext(context *Context) { opts.opts.Context = context.context } | ||||||
|  |  | ||||||
|  | // BoundContract is the base wrapper object that reflects a contract on the | ||||||
|  | // Ethereum network. It contains a collection of methods that are used by the | ||||||
|  | // higher level contract bindings to operate. | ||||||
|  | type BoundContract struct { | ||||||
|  | 	contract *bind.BoundContract | ||||||
|  | 	address  common.Address | ||||||
|  | 	deployer *types.Transaction | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // DeployContract deploys a contract onto the Ethereum blockchain and binds the | ||||||
|  | // deployment address with a wrapper. | ||||||
|  | func DeployContract(opts *TransactOpts, abiJSON string, bytecode []byte, client *EthereumClient, args *Interfaces) (*BoundContract, error) { | ||||||
|  | 	// Convert all the deployment parameters to Go types | ||||||
|  | 	params := make([]interface{}, len(args.objects)) | ||||||
|  | 	for i, obj := range args.objects { | ||||||
|  | 		params[i] = obj | ||||||
|  | 	} | ||||||
|  | 	// Deploy the contract to the network | ||||||
|  | 	parsed, err := abi.JSON(strings.NewReader(abiJSON)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	addr, tx, bound, err := bind.DeployContract(&opts.opts, parsed, bytecode, client.client, params...) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return &BoundContract{ | ||||||
|  | 		contract: bound, | ||||||
|  | 		address:  addr, | ||||||
|  | 		deployer: tx, | ||||||
|  | 	}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // BindContract creates a low level contract interface through which calls and | ||||||
|  | // transactions may be made through. | ||||||
|  | func BindContract(address *Address, abiJSON string, client *EthereumClient) (*BoundContract, error) { | ||||||
|  | 	parsed, err := abi.JSON(strings.NewReader(abiJSON)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return &BoundContract{ | ||||||
|  | 		contract: bind.NewBoundContract(address.address, parsed, client.client, client.client), | ||||||
|  | 		address:  address.address, | ||||||
|  | 	}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c *BoundContract) GetAddress() *Address { return &Address{c.address} } | ||||||
|  | func (c *BoundContract) GetDeployer() *Transaction { | ||||||
|  | 	if c.deployer == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return &Transaction{c.deployer} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Call invokes the (constant) contract method with params as input values and | ||||||
|  | // sets the output to result. | ||||||
|  | func (c *BoundContract) Call(opts *CallOpts, out *Interfaces, method string, args *Interfaces) error { | ||||||
|  | 	// Convert all the input and output parameters to Go types | ||||||
|  | 	params := make([]interface{}, len(args.objects)) | ||||||
|  | 	for i, obj := range args.objects { | ||||||
|  | 		params[i] = obj | ||||||
|  | 	} | ||||||
|  | 	results := make([]interface{}, len(out.objects)) | ||||||
|  | 	for i, obj := range out.objects { | ||||||
|  | 		results[i] = obj | ||||||
|  | 	} | ||||||
|  | 	// Execute the call to the contract and wrap any results | ||||||
|  | 	if err := c.contract.Call(&opts.opts, &results, method, params...); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	for i, res := range results { | ||||||
|  | 		out.objects[i] = res | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Transact invokes the (paid) contract method with params as input values. | ||||||
|  | func (c *BoundContract) Transact(opts *TransactOpts, method string, args *Interfaces) (*Transaction, error) { | ||||||
|  | 	params := make([]interface{}, len(args.objects)) | ||||||
|  | 	for i, obj := range args.objects { | ||||||
|  | 		params[i] = obj | ||||||
|  | 	} | ||||||
|  | 	tx, err := c.contract.Transact(&opts.opts, method, params) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return &Transaction{tx}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Transfer initiates a plain transaction to move funds to the contract, calling | ||||||
|  | // its default method if one is available. | ||||||
|  | func (c *BoundContract) Transfer(opts *TransactOpts) (*Transaction, error) { | ||||||
|  | 	tx, err := c.contract.Transfer(&opts.opts) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return &Transaction{tx}, nil | ||||||
|  | } | ||||||
							
								
								
									
										187
									
								
								mobile/common.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								mobile/common.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains all the wrappers from the common package. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"encoding/hex" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
|  | 	"github.com/ethereum/go-ethereum/common" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Hash represents the 32 byte Keccak256 hash of arbitrary data. | ||||||
|  | type Hash struct { | ||||||
|  | 	hash common.Hash | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewHashFromBytes converts a slice of bytes to a hash value. | ||||||
|  | func NewHashFromBytes(hash []byte) (*Hash, error) { | ||||||
|  | 	h := new(Hash) | ||||||
|  | 	if err := h.SetBytes(hash); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return h, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewHashFromHex converts a hex string to a hash value. | ||||||
|  | func NewHashFromHex(hash string) (*Hash, error) { | ||||||
|  | 	h := new(Hash) | ||||||
|  | 	if err := h.SetHex(hash); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return h, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetBytes sets the specified slice of bytes as the hash value. | ||||||
|  | func (h *Hash) SetBytes(hash []byte) error { | ||||||
|  | 	if length := len(hash); length != common.HashLength { | ||||||
|  | 		return fmt.Errorf("invalid hash length: %v != %v", length, common.HashLength) | ||||||
|  | 	} | ||||||
|  | 	copy(h.hash[:], hash) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetBytes retrieves the byte representation of the hash. | ||||||
|  | func (h *Hash) GetBytes() []byte { | ||||||
|  | 	return h.hash[:] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetHex sets the specified hex string as the hash value. | ||||||
|  | func (h *Hash) SetHex(hash string) error { | ||||||
|  | 	hash = strings.ToLower(hash) | ||||||
|  | 	if len(hash) >= 2 && hash[:2] == "0x" { | ||||||
|  | 		hash = hash[2:] | ||||||
|  | 	} | ||||||
|  | 	if length := len(hash); length != 2*common.HashLength { | ||||||
|  | 		return fmt.Errorf("invalid hash hex length: %v != %v", length, 2*common.HashLength) | ||||||
|  | 	} | ||||||
|  | 	bin, err := hex.DecodeString(hash) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	copy(h.hash[:], bin) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetHex retrieves the hex string representation of the hash. | ||||||
|  | func (h *Hash) GetHex() string { | ||||||
|  | 	return h.hash.Hex() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Hashes represents a slice of hashes. | ||||||
|  | type Hashes struct{ hashes []common.Hash } | ||||||
|  |  | ||||||
|  | // Size returns the number of hashes in the slice. | ||||||
|  | func (h *Hashes) Size() int { | ||||||
|  | 	return len(h.hashes) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the hash at the given index from the slice. | ||||||
|  | func (h *Hashes) Get(index int) (*Hash, error) { | ||||||
|  | 	if index < 0 || index >= len(h.hashes) { | ||||||
|  | 		return nil, errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	return &Hash{h.hashes[index]}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Address represents the 20 byte address of an Ethereum account. | ||||||
|  | type Address struct { | ||||||
|  | 	address common.Address | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewAddressFromBytes converts a slice of bytes to a hash value. | ||||||
|  | func NewAddressFromBytes(address []byte) (*Address, error) { | ||||||
|  | 	a := new(Address) | ||||||
|  | 	if err := a.SetBytes(address); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return a, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewAddressFromHex converts a hex string to a address value. | ||||||
|  | func NewAddressFromHex(address string) (*Address, error) { | ||||||
|  | 	a := new(Address) | ||||||
|  | 	if err := a.SetHex(address); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return a, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetBytes sets the specified slice of bytes as the address value. | ||||||
|  | func (a *Address) SetBytes(address []byte) error { | ||||||
|  | 	if length := len(address); length != common.AddressLength { | ||||||
|  | 		return fmt.Errorf("invalid address length: %v != %v", length, common.AddressLength) | ||||||
|  | 	} | ||||||
|  | 	copy(a.address[:], address) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetBytes retrieves the byte representation of the address. | ||||||
|  | func (a *Address) GetBytes() []byte { | ||||||
|  | 	return a.address[:] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetHex sets the specified hex string as the address value. | ||||||
|  | func (a *Address) SetHex(address string) error { | ||||||
|  | 	address = strings.ToLower(address) | ||||||
|  | 	if len(address) >= 2 && address[:2] == "0x" { | ||||||
|  | 		address = address[2:] | ||||||
|  | 	} | ||||||
|  | 	if length := len(address); length != 2*common.AddressLength { | ||||||
|  | 		return fmt.Errorf("invalid address hex length: %v != %v", length, 2*common.AddressLength) | ||||||
|  | 	} | ||||||
|  | 	bin, err := hex.DecodeString(address) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	copy(a.address[:], bin) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetHex retrieves the hex string representation of the address. | ||||||
|  | func (a *Address) GetHex() string { | ||||||
|  | 	return a.address.Hex() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Addresses represents a slice of addresses. | ||||||
|  | type Addresses struct{ addresses []common.Address } | ||||||
|  |  | ||||||
|  | // Size returns the number of addresses in the slice. | ||||||
|  | func (a *Addresses) Size() int { | ||||||
|  | 	return len(a.addresses) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the address at the given index from the slice. | ||||||
|  | func (a *Addresses) Get(index int) (*Address, error) { | ||||||
|  | 	if index < 0 || index >= len(a.addresses) { | ||||||
|  | 		return nil, errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	return &Address{a.addresses[index]}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Set sets the address at the given index in the slice. | ||||||
|  | func (a *Addresses) Set(index int, address *Address) error { | ||||||
|  | 	if index < 0 || index >= len(a.addresses) { | ||||||
|  | 		return errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	a.addresses[index] = address.address | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										81
									
								
								mobile/context.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								mobile/context.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains all the wrappers from the golang.org/x/net/context package to support | ||||||
|  | // client side context management on mobile platforms. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"golang.org/x/net/context" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Context carries a deadline, a cancelation signal, and other values across API | ||||||
|  | // boundaries. | ||||||
|  | type Context struct { | ||||||
|  | 	context context.Context | ||||||
|  | 	cancel  context.CancelFunc | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewContext returns a non-nil, empty Context. It is never canceled, has no | ||||||
|  | // values, and has no deadline. It is typically used by the main function, | ||||||
|  | // initialization, and tests, and as the top-level Context for incoming requests. | ||||||
|  | func NewContext() *Context { | ||||||
|  | 	return &Context{ | ||||||
|  | 		context: context.Background(), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // WithCancel returns a copy of the original context with cancellation mechanism | ||||||
|  | // included. | ||||||
|  | // | ||||||
|  | // Canceling this context releases resources associated with it, so code should | ||||||
|  | // call cancel as soon as the operations running in this Context complete. | ||||||
|  | func (c *Context) WithCancel() *Context { | ||||||
|  | 	child, cancel := context.WithCancel(c.context) | ||||||
|  | 	return &Context{ | ||||||
|  | 		context: child, | ||||||
|  | 		cancel:  cancel, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // WithDeadline returns a copy of the original context with the deadline adjusted | ||||||
|  | // to be no later than the specified time. | ||||||
|  | // | ||||||
|  | // Canceling this context releases resources associated with it, so code should | ||||||
|  | // call cancel as soon as the operations running in this Context complete. | ||||||
|  | func (c *Context) WithDeadline(sec int64, nsec int64) *Context { | ||||||
|  | 	child, cancel := context.WithDeadline(c.context, time.Unix(sec, nsec)) | ||||||
|  | 	return &Context{ | ||||||
|  | 		context: child, | ||||||
|  | 		cancel:  cancel, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // WithTimeout returns a copy of the original context with the deadline adjusted | ||||||
|  | // to be no later than now + the duration specified. | ||||||
|  | // | ||||||
|  | // Canceling this context releases resources associated with it, so code should | ||||||
|  | // call cancel as soon as the operations running in this Context complete. | ||||||
|  | func (c *Context) WithTimeout(nsec int64) *Context { | ||||||
|  | 	child, cancel := context.WithTimeout(c.context, time.Duration(nsec)) | ||||||
|  | 	return &Context{ | ||||||
|  | 		context: child, | ||||||
|  | 		cancel:  cancel, | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										58
									
								
								mobile/core.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								mobile/core.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains all the wrappers from the core package. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/ethereum/go-ethereum/core" | ||||||
|  | 	"github.com/ethereum/go-ethereum/params" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // MainnetChainConfig is the chain configurations for the main Ethereum network. | ||||||
|  | var MainnetChainConfig = &ChainConfig{ | ||||||
|  | 	HomesteadBlock: params.MainNetHomesteadBlock.Int64(), | ||||||
|  | 	DAOForkBlock:   params.MainNetDAOForkBlock.Int64(), | ||||||
|  | 	DAOForkSupport: true, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // MainnetGenesis is the JSON spec to use for the main Ethereum network. It is | ||||||
|  | // actually empty since that defaults to the hard coded binary genesis block. | ||||||
|  | var MainnetGenesis = "" | ||||||
|  |  | ||||||
|  | // TestnetChainConfig is the chain configurations for the Ethereum test network. | ||||||
|  | var TestnetChainConfig = &ChainConfig{ | ||||||
|  | 	HomesteadBlock: params.TestNetHomesteadBlock.Int64(), | ||||||
|  | 	DAOForkBlock:   0, | ||||||
|  | 	DAOForkSupport: false, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TestnetGenesis is the JSON spec to use for the Ethereum test network. | ||||||
|  | var TestnetGenesis = core.TestNetGenesisBlock() | ||||||
|  |  | ||||||
|  | // ChainConfig is the core config which determines the blockchain settings. | ||||||
|  | type ChainConfig struct { | ||||||
|  | 	HomesteadBlock int64 // Homestead switch block | ||||||
|  | 	DAOForkBlock   int64 // TheDAO hard-fork switch block | ||||||
|  | 	DAOForkSupport bool  // Whether the nodes supports or opposes the DAO hard-fork | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewChainConfig creates a new chain configuration that transitions immediately | ||||||
|  | // to homestead and has no notion of the DAO fork (ideal for a private network). | ||||||
|  | func NewChainConfig() *ChainConfig { | ||||||
|  | 	return new(ChainConfig) | ||||||
|  | } | ||||||
							
								
								
									
										129
									
								
								mobile/discover.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								mobile/discover.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains all the wrappers from the accounts package to support client side enode | ||||||
|  | // management on mobile platforms. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  |  | ||||||
|  | 	"github.com/ethereum/go-ethereum/cmd/utils" | ||||||
|  | 	"github.com/ethereum/go-ethereum/p2p/discover" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // MainnetBootnodes returns the enode URLs of the P2P bootstrap nodes running | ||||||
|  | // on the main network. | ||||||
|  | // | ||||||
|  | // Note, this needs to be a method to prevent gomobile generating a setter for it. | ||||||
|  | func MainnetBootnodes() *Enodes { | ||||||
|  | 	nodes := &Enodes{nodes: make([]*discover.Node, len(utils.MainnetBootnodes))} | ||||||
|  | 	for i, node := range utils.MainnetBootnodes { | ||||||
|  | 		nodes.nodes[i] = node | ||||||
|  | 	} | ||||||
|  | 	return nodes | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TestnetBootnodes returns the enode URLs of the P2P bootstrap nodes running | ||||||
|  | // on the test network. | ||||||
|  | // | ||||||
|  | // Note, this needs to be a method to prevent gomobile generating a setter for it. | ||||||
|  | func TestnetBootnodes() *Enodes { | ||||||
|  | 	nodes := &Enodes{nodes: make([]*discover.Node, len(utils.TestnetBootnodes))} | ||||||
|  | 	for i, node := range utils.TestnetBootnodes { | ||||||
|  | 		nodes.nodes[i] = node | ||||||
|  | 	} | ||||||
|  | 	return nodes | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Enode represents a host on the network. | ||||||
|  | type Enode struct { | ||||||
|  | 	node *discover.Node | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewEnode parses a node designator. | ||||||
|  | // | ||||||
|  | // There are two basic forms of node designators | ||||||
|  | //   - incomplete nodes, which only have the public key (node ID) | ||||||
|  | //   - complete nodes, which contain the public key and IP/Port information | ||||||
|  | // | ||||||
|  | // For incomplete nodes, the designator must look like one of these | ||||||
|  | // | ||||||
|  | //    enode://<hex node id> | ||||||
|  | //    <hex node id> | ||||||
|  | // | ||||||
|  | // For complete nodes, the node ID is encoded in the username portion | ||||||
|  | // of the URL, separated from the host by an @ sign. The hostname can | ||||||
|  | // only be given as an IP address, DNS domain names are not allowed. | ||||||
|  | // The port in the host name section is the TCP listening port. If the | ||||||
|  | // TCP and UDP (discovery) ports differ, the UDP port is specified as | ||||||
|  | // query parameter "discport". | ||||||
|  | // | ||||||
|  | // In the following example, the node URL describes | ||||||
|  | // a node with IP address 10.3.58.6, TCP listening port 30303 | ||||||
|  | // and UDP discovery port 30301. | ||||||
|  | // | ||||||
|  | //    enode://<hex node id>@10.3.58.6:30303?discport=30301 | ||||||
|  | func NewEnode(rawurl string) (*Enode, error) { | ||||||
|  | 	node, err := discover.ParseNode(rawurl) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return &Enode{node}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Enodes represents a slice of accounts. | ||||||
|  | type Enodes struct{ nodes []*discover.Node } | ||||||
|  |  | ||||||
|  | // NewEnodes creates a slice of uninitialized enodes. | ||||||
|  | func NewEnodes(size int) *Enodes { | ||||||
|  | 	return &Enodes{ | ||||||
|  | 		nodes: make([]*discover.Node, size), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewEnodesEmpty creates an empty slice of Enode values. | ||||||
|  | func NewEnodesEmpty() *Enodes { | ||||||
|  | 	return NewEnodes(0) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Size returns the number of enodes in the slice. | ||||||
|  | func (e *Enodes) Size() int { | ||||||
|  | 	return len(e.nodes) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the enode at the given index from the slice. | ||||||
|  | func (e *Enodes) Get(index int) (*Enode, error) { | ||||||
|  | 	if index < 0 || index >= len(e.nodes) { | ||||||
|  | 		return nil, errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	return &Enode{e.nodes[index]}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Set sets the enode at the given index in the slice. | ||||||
|  | func (e *Enodes) Set(index int, enode *Enode) error { | ||||||
|  | 	if index < 0 || index >= len(e.nodes) { | ||||||
|  | 		return errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	e.nodes[index] = enode.node | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Append adds a new enode element to the end of the slice. | ||||||
|  | func (e *Enodes) Append(enode *Enode) { | ||||||
|  | 	e.nodes = append(e.nodes, enode.node) | ||||||
|  | } | ||||||
							
								
								
									
										57
									
								
								mobile/doc.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								mobile/doc.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Package geth contains the simplified mobile APIs to go-ethereum. | ||||||
|  | // | ||||||
|  | // The scope of this package is *not* to allow writing a custom Ethereun client | ||||||
|  | // with pieces plucked from go-ethereum, rather to allow writing native dapps on | ||||||
|  | // mobile platforms. Keep this in mind when using or extending this package! | ||||||
|  | // | ||||||
|  | // API limitations | ||||||
|  | // | ||||||
|  | // Since gomobile cannot bridge arbitrary types between Go and Android/iOS, the | ||||||
|  | // exposed APIs need to be manually wrapped into simplified types, with custom | ||||||
|  | // constructors and getters/setters to ensure that they can be meaninfully used | ||||||
|  | // from Java/ObjC too. | ||||||
|  | // | ||||||
|  | // With this in mind, please try to limit the scope of this package and only add | ||||||
|  | // essentials without which mobile support cannot work, especially since manually | ||||||
|  | // syncing the code will be unwieldy otherwise. In the long term we might consider | ||||||
|  | // writing custom library generators, but those are out of scope now. | ||||||
|  | // | ||||||
|  | // Content wise each file in this package corresponds to an entire Go package | ||||||
|  | // from the go-ethereum repository. Please adhere to this scoping to prevent this | ||||||
|  | // package getting unmaintainable. | ||||||
|  | // | ||||||
|  | // Wrapping guidelines: | ||||||
|  | // | ||||||
|  | // Every type that is to be exposed should be wrapped into its own plain struct, | ||||||
|  | // which internally contains a single field: the original go-ethereum version. | ||||||
|  | // This is needed because gomobile cannot expose named types for now. | ||||||
|  | // | ||||||
|  | // Whenever a method argument or a return type is a custom struct, the pointer | ||||||
|  | // variant should always be used as value types crossing over between language | ||||||
|  | // boundaries might have strange behaviors. | ||||||
|  | // | ||||||
|  | // Slices of types should be converted into a single multiplicative type wrapping | ||||||
|  | // a go slice with the methods `Size`, `Get` and `Set`. Further slice operations | ||||||
|  | // should not be provided to limit the remote code complexity. Arrays should be | ||||||
|  | // avoided as much as possible since they complicate bounds checking. | ||||||
|  | // | ||||||
|  | // Note, a panic *cannot* cross over language boundaries, instead will result in | ||||||
|  | // an undebuggable SEGFAULT in the process. For error handling only ever use error | ||||||
|  | // returns, which may be the only or the second return. | ||||||
|  | package geth | ||||||
							
								
								
									
										305
									
								
								mobile/ethclient.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										305
									
								
								mobile/ethclient.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,305 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains a wrapper for the Ethereum client. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"math/big" | ||||||
|  |  | ||||||
|  | 	"github.com/ethereum/go-ethereum/core/types" | ||||||
|  | 	"github.com/ethereum/go-ethereum/core/vm" | ||||||
|  | 	"github.com/ethereum/go-ethereum/ethclient" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // EthereumClient provides access to the Ethereum APIs. | ||||||
|  | type EthereumClient struct { | ||||||
|  | 	client *ethclient.Client | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewEthereumClient connects a client to the given URL. | ||||||
|  | func NewEthereumClient(rawurl string) (*EthereumClient, error) { | ||||||
|  | 	client, err := ethclient.Dial(rawurl) | ||||||
|  | 	return &EthereumClient{client}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetBlockByHash returns the given full block. | ||||||
|  | func (ec *EthereumClient) GetBlockByHash(ctx *Context, hash *Hash) (*Block, error) { | ||||||
|  | 	block, err := ec.client.BlockByHash(ctx.context, hash.hash) | ||||||
|  | 	return &Block{block}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetBlockByNumber returns a block from the current canonical chain. If number is <0, the | ||||||
|  | // latest known block is returned. | ||||||
|  | func (ec *EthereumClient) GetBlockByNumber(ctx *Context, number int64) (*Block, error) { | ||||||
|  | 	if number < 0 { | ||||||
|  | 		block, err := ec.client.BlockByNumber(ctx.context, nil) | ||||||
|  | 		return &Block{block}, err | ||||||
|  | 	} | ||||||
|  | 	block, err := ec.client.BlockByNumber(ctx.context, big.NewInt(number)) | ||||||
|  | 	return &Block{block}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetHeaderByHash returns the block header with the given hash. | ||||||
|  | func (ec *EthereumClient) GetHeaderByHash(ctx *Context, hash *Hash) (*Header, error) { | ||||||
|  | 	header, err := ec.client.HeaderByHash(ctx.context, hash.hash) | ||||||
|  | 	return &Header{header}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetHeaderByNumber returns a block header from the current canonical chain. If number is <0, | ||||||
|  | // the latest known header is returned. | ||||||
|  | func (ec *EthereumClient) GetHeaderByNumber(ctx *Context, number int64) (*Header, error) { | ||||||
|  | 	if number < 0 { | ||||||
|  | 		header, err := ec.client.HeaderByNumber(ctx.context, nil) | ||||||
|  | 		return &Header{header}, err | ||||||
|  | 	} | ||||||
|  | 	header, err := ec.client.HeaderByNumber(ctx.context, big.NewInt(number)) | ||||||
|  | 	return &Header{header}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetTransactionByHash returns the transaction with the given hash. | ||||||
|  | func (ec *EthereumClient) GetTransactionByHash(ctx *Context, hash *Hash) (*Transaction, error) { | ||||||
|  | 	tx, err := ec.client.TransactionByHash(ctx.context, hash.hash) | ||||||
|  | 	return &Transaction{tx}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetTransactionCount returns the total number of transactions in the given block. | ||||||
|  | func (ec *EthereumClient) GetTransactionCount(ctx *Context, hash *Hash) (int, error) { | ||||||
|  | 	count, err := ec.client.TransactionCount(ctx.context, hash.hash) | ||||||
|  | 	return int(count), err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetTransactionInBlock returns a single transaction at index in the given block. | ||||||
|  | func (ec *EthereumClient) GetTransactionInBlock(ctx *Context, hash *Hash, index int) (*Transaction, error) { | ||||||
|  | 	tx, err := ec.client.TransactionInBlock(ctx.context, hash.hash, uint(index)) | ||||||
|  | 	return &Transaction{tx}, err | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetTransactionReceipt returns the receipt of a transaction by transaction hash. | ||||||
|  | // Note that the receipt is not available for pending transactions. | ||||||
|  | func (ec *EthereumClient) GetTransactionReceipt(ctx *Context, hash *Hash) (*Receipt, error) { | ||||||
|  | 	receipt, err := ec.client.TransactionReceipt(ctx.context, hash.hash) | ||||||
|  | 	return &Receipt{receipt}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SyncProgress retrieves the current progress of the sync algorithm. If there's | ||||||
|  | // no sync currently running, it returns nil. | ||||||
|  | func (ec *EthereumClient) SyncProgress(ctx *Context) (*SyncProgress, error) { | ||||||
|  | 	progress, err := ec.client.SyncProgress(ctx.context) | ||||||
|  | 	if progress == nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return &SyncProgress{*progress}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewHeadHandler is a client-side subscription callback to invoke on events and | ||||||
|  | // subscription failure. | ||||||
|  | type NewHeadHandler interface { | ||||||
|  | 	OnNewHead(header *Header) | ||||||
|  | 	OnError(failure string) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SubscribeNewHead subscribes to notifications about the current blockchain head | ||||||
|  | // on the given channel. | ||||||
|  | func (ec *EthereumClient) SubscribeNewHead(ctx *Context, handler NewHeadHandler, buffer int) (*Subscription, error) { | ||||||
|  | 	// Subscribe to the event internally | ||||||
|  | 	ch := make(chan *types.Header, buffer) | ||||||
|  | 	sub, err := ec.client.SubscribeNewHead(ctx.context, ch) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	// Start up a dispatcher to feed into the callback | ||||||
|  | 	go func() { | ||||||
|  | 		for { | ||||||
|  | 			select { | ||||||
|  | 			case header := <-ch: | ||||||
|  | 				handler.OnNewHead(&Header{header}) | ||||||
|  |  | ||||||
|  | 			case err := <-sub.Err(): | ||||||
|  | 				handler.OnError(err.Error()) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  | 	return &Subscription{sub}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // State Access | ||||||
|  |  | ||||||
|  | // GetBalanceAt returns the wei balance of the given account. | ||||||
|  | // The block number can be <0, in which case the balance is taken from the latest known block. | ||||||
|  | func (ec *EthereumClient) GetBalanceAt(ctx *Context, account *Address, number int64) (*BigInt, error) { | ||||||
|  | 	if number < 0 { | ||||||
|  | 		balance, err := ec.client.BalanceAt(ctx.context, account.address, nil) | ||||||
|  | 		return &BigInt{balance}, err | ||||||
|  | 	} | ||||||
|  | 	balance, err := ec.client.BalanceAt(ctx.context, account.address, big.NewInt(number)) | ||||||
|  | 	return &BigInt{balance}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetStorageAt returns the value of key in the contract storage of the given account. | ||||||
|  | // The block number can be <0, in which case the value is taken from the latest known block. | ||||||
|  | func (ec *EthereumClient) GetStorageAt(ctx *Context, account *Address, key *Hash, number int64) ([]byte, error) { | ||||||
|  | 	if number < 0 { | ||||||
|  | 		return ec.client.StorageAt(ctx.context, account.address, key.hash, nil) | ||||||
|  | 	} | ||||||
|  | 	return ec.client.StorageAt(ctx.context, account.address, key.hash, big.NewInt(number)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetCodeAt returns the contract code of the given account. | ||||||
|  | // The block number can be <0, in which case the code is taken from the latest known block. | ||||||
|  | func (ec *EthereumClient) GetCodeAt(ctx *Context, account *Address, number int64) ([]byte, error) { | ||||||
|  | 	if number < 0 { | ||||||
|  | 		return ec.client.CodeAt(ctx.context, account.address, nil) | ||||||
|  | 	} | ||||||
|  | 	return ec.client.CodeAt(ctx.context, account.address, big.NewInt(number)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetNonceAt returns the account nonce of the given account. | ||||||
|  | // The block number can be <0, in which case the nonce is taken from the latest known block. | ||||||
|  | func (ec *EthereumClient) GetNonceAt(ctx *Context, account *Address, number int64) (int64, error) { | ||||||
|  | 	if number < 0 { | ||||||
|  | 		nonce, err := ec.client.NonceAt(ctx.context, account.address, nil) | ||||||
|  | 		return int64(nonce), err | ||||||
|  | 	} | ||||||
|  | 	nonce, err := ec.client.NonceAt(ctx.context, account.address, big.NewInt(number)) | ||||||
|  | 	return int64(nonce), err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Filters | ||||||
|  |  | ||||||
|  | // FilterLogs executes a filter query. | ||||||
|  | func (ec *EthereumClient) FilterLogs(ctx *Context, query *FilterQuery) (*Logs, error) { | ||||||
|  | 	logs, err := ec.client.FilterLogs(ctx.context, query.query) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	// Temp hack due to vm.Logs being []*vm.Log | ||||||
|  | 	res := make(vm.Logs, len(logs)) | ||||||
|  | 	for i, log := range logs { | ||||||
|  | 		res[i] = &log | ||||||
|  | 	} | ||||||
|  | 	return &Logs{res}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // FilterLogsHandler is a client-side subscription callback to invoke on events and | ||||||
|  | // subscription failure. | ||||||
|  | type FilterLogsHandler interface { | ||||||
|  | 	OnFilterLogs(log *Log) | ||||||
|  | 	OnError(failure string) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SubscribeFilterLogs subscribes to the results of a streaming filter query. | ||||||
|  | func (ec *EthereumClient) SubscribeFilterLogs(ctx *Context, query *FilterQuery, handler FilterLogsHandler, buffer int) (*Subscription, error) { | ||||||
|  | 	// Subscribe to the event internally | ||||||
|  | 	ch := make(chan vm.Log, buffer) | ||||||
|  | 	sub, err := ec.client.SubscribeFilterLogs(ctx.context, query.query, ch) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	// Start up a dispatcher to feed into the callback | ||||||
|  | 	go func() { | ||||||
|  | 		for { | ||||||
|  | 			select { | ||||||
|  | 			case log := <-ch: | ||||||
|  | 				handler.OnFilterLogs(&Log{&log}) | ||||||
|  |  | ||||||
|  | 			case err := <-sub.Err(): | ||||||
|  | 				handler.OnError(err.Error()) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  | 	return &Subscription{sub}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Pending State | ||||||
|  |  | ||||||
|  | // GetPendingBalanceAt returns the wei balance of the given account in the pending state. | ||||||
|  | func (ec *EthereumClient) GetPendingBalanceAt(ctx *Context, account *Address) (*BigInt, error) { | ||||||
|  | 	balance, err := ec.client.PendingBalanceAt(ctx.context, account.address) | ||||||
|  | 	return &BigInt{balance}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetPendingStorageAt returns the value of key in the contract storage of the given account in the pending state. | ||||||
|  | func (ec *EthereumClient) GetPendingStorageAt(ctx *Context, account *Address, key *Hash) ([]byte, error) { | ||||||
|  | 	return ec.client.PendingStorageAt(ctx.context, account.address, key.hash) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetPendingCodeAt returns the contract code of the given account in the pending state. | ||||||
|  | func (ec *EthereumClient) GetPendingCodeAt(ctx *Context, account *Address) ([]byte, error) { | ||||||
|  | 	return ec.client.PendingCodeAt(ctx.context, account.address) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetPendingNonceAt returns the account nonce of the given account in the pending state. | ||||||
|  | // This is the nonce that should be used for the next transaction. | ||||||
|  | func (ec *EthereumClient) GetPendingNonceAt(ctx *Context, account *Address) (int64, error) { | ||||||
|  | 	nonce, err := ec.client.PendingNonceAt(ctx.context, account.address) | ||||||
|  | 	return int64(nonce), err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetPendingTransactionCount returns the total number of transactions in the pending state. | ||||||
|  | func (ec *EthereumClient) GetPendingTransactionCount(ctx *Context) (int, error) { | ||||||
|  | 	count, err := ec.client.PendingTransactionCount(ctx.context) | ||||||
|  | 	return int(count), err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Contract Calling | ||||||
|  |  | ||||||
|  | // CallContract executes a message call transaction, which is directly executed in the VM | ||||||
|  | // of the node, but never mined into the blockchain. | ||||||
|  | // | ||||||
|  | // blockNumber selects the block height at which the call runs. It can be <0, in which | ||||||
|  | // case the code is taken from the latest known block. Note that state from very old | ||||||
|  | // blocks might not be available. | ||||||
|  | func (ec *EthereumClient) CallContract(ctx *Context, msg *CallMsg, number int64) ([]byte, error) { | ||||||
|  | 	if number < 0 { | ||||||
|  | 		return ec.client.CallContract(ctx.context, msg.msg, nil) | ||||||
|  | 	} | ||||||
|  | 	return ec.client.CallContract(ctx.context, msg.msg, big.NewInt(number)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // PendingCallContract executes a message call transaction using the EVM. | ||||||
|  | // The state seen by the contract call is the pending state. | ||||||
|  | func (ec *EthereumClient) PendingCallContract(ctx *Context, msg *CallMsg) ([]byte, error) { | ||||||
|  | 	return ec.client.PendingCallContract(ctx.context, msg.msg) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SuggestGasPrice retrieves the currently suggested gas price to allow a timely | ||||||
|  | // execution of a transaction. | ||||||
|  | func (ec *EthereumClient) SuggestGasPrice(ctx *Context) (*BigInt, error) { | ||||||
|  | 	price, err := ec.client.SuggestGasPrice(ctx.context) | ||||||
|  | 	return &BigInt{price}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // EstimateGas tries to estimate the gas needed to execute a specific transaction based on | ||||||
|  | // the current pending state of the backend blockchain. There is no guarantee that this is | ||||||
|  | // the true gas limit requirement as other transactions may be added or removed by miners, | ||||||
|  | // but it should provide a basis for setting a reasonable default. | ||||||
|  | func (ec *EthereumClient) EstimateGas(ctx *Context, msg *CallMsg) (*BigInt, error) { | ||||||
|  | 	price, err := ec.client.EstimateGas(ctx.context, msg.msg) | ||||||
|  | 	return &BigInt{price}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SendTransaction injects a signed transaction into the pending pool for execution. | ||||||
|  | // | ||||||
|  | // If the transaction was a contract creation use the TransactionReceipt method to get the | ||||||
|  | // contract address after the transaction has been mined. | ||||||
|  | func (ec *EthereumClient) SendTransaction(ctx *Context, tx *Transaction) error { | ||||||
|  | 	return ec.client.SendTransaction(ctx.context, tx.tx) | ||||||
|  | } | ||||||
							
								
								
									
										125
									
								
								mobile/ethereum.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								mobile/ethereum.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains all the wrappers from the go-ethereum root package. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"math/big" | ||||||
|  |  | ||||||
|  | 	ethereum "github.com/ethereum/go-ethereum" | ||||||
|  | 	"github.com/ethereum/go-ethereum/common" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Subscription represents an event subscription where events are | ||||||
|  | // delivered on a data channel. | ||||||
|  | type Subscription struct { | ||||||
|  | 	sub ethereum.Subscription | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Unsubscribe cancels the sending of events to the data channel | ||||||
|  | // and closes the error channel. | ||||||
|  | func (s *Subscription) Unsubscribe() { | ||||||
|  | 	s.sub.Unsubscribe() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // CallMsg contains parameters for contract calls. | ||||||
|  | type CallMsg struct { | ||||||
|  | 	msg ethereum.CallMsg | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewCallMsg creates an empty contract call parameter list. | ||||||
|  | func NewCallMsg() *CallMsg { | ||||||
|  | 	return new(CallMsg) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (msg *CallMsg) GetFrom() *Address    { return &Address{msg.msg.From} } | ||||||
|  | func (msg *CallMsg) GetGas() int64        { return msg.msg.Gas.Int64() } | ||||||
|  | func (msg *CallMsg) GetGasPrice() *BigInt { return &BigInt{msg.msg.GasPrice} } | ||||||
|  | func (msg *CallMsg) GetValue() *BigInt    { return &BigInt{msg.msg.Value} } | ||||||
|  | func (msg *CallMsg) GetData() []byte      { return msg.msg.Data } | ||||||
|  | func (msg *CallMsg) GetTo() *Address { | ||||||
|  | 	if to := msg.msg.To; to != nil { | ||||||
|  | 		return &Address{*msg.msg.To} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (msg *CallMsg) SetFrom(address *Address)  { msg.msg.From = address.address } | ||||||
|  | func (msg *CallMsg) SetGas(gas int64)          { msg.msg.Gas = big.NewInt(gas) } | ||||||
|  | func (msg *CallMsg) SetGasPrice(price *BigInt) { msg.msg.GasPrice = price.bigint } | ||||||
|  | func (msg *CallMsg) SetValue(value *BigInt)    { msg.msg.Value = value.bigint } | ||||||
|  | func (msg *CallMsg) SetData(data []byte)       { msg.msg.Data = data } | ||||||
|  | func (msg *CallMsg) SetTo(address *Address) { | ||||||
|  | 	if address == nil { | ||||||
|  | 		msg.msg.To = nil | ||||||
|  | 	} | ||||||
|  | 	msg.msg.To = &address.address | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SyncProgress gives progress indications when the node is synchronising with | ||||||
|  | // the Ethereum network. | ||||||
|  | type SyncProgress struct { | ||||||
|  | 	progress ethereum.SyncProgress | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *SyncProgress) GetStartingBlock() int64 { return int64(p.progress.StartingBlock) } | ||||||
|  | func (p *SyncProgress) GetCurrentBlock() int64  { return int64(p.progress.CurrentBlock) } | ||||||
|  | func (p *SyncProgress) GetHighestBlock() int64  { return int64(p.progress.HighestBlock) } | ||||||
|  | func (p *SyncProgress) GetPulledStates() int64  { return int64(p.progress.PulledStates) } | ||||||
|  | func (p *SyncProgress) GetKnownStates() int64   { return int64(p.progress.KnownStates) } | ||||||
|  |  | ||||||
|  | // Topics is a set of topic lists to filter events with. | ||||||
|  | type Topics struct{ topics [][]common.Hash } | ||||||
|  |  | ||||||
|  | // Size returns the number of topic lists inside the set | ||||||
|  | func (t *Topics) Size() int { | ||||||
|  | 	return len(t.topics) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the topic list at the given index from the slice. | ||||||
|  | func (t *Topics) Get(index int) (*Hashes, error) { | ||||||
|  | 	if index < 0 || index >= len(t.topics) { | ||||||
|  | 		return nil, errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	return &Hashes{t.topics[index]}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Set sets the topic list at the given index in the slice. | ||||||
|  | func (t *Topics) Set(index int, topics *Hashes) error { | ||||||
|  | 	if index < 0 || index >= len(t.topics) { | ||||||
|  | 		return errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	t.topics[index] = topics.hashes | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // FilterQuery contains options for contact log filtering. | ||||||
|  | type FilterQuery struct { | ||||||
|  | 	query ethereum.FilterQuery | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewFilterQuery creates an empty filter query for contact log filtering. | ||||||
|  | func NewFilterQuery() *FilterQuery { | ||||||
|  | 	return new(FilterQuery) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (fq *FilterQuery) GetFromBlock() *BigInt    { return &BigInt{fq.query.FromBlock} } | ||||||
|  | func (fq *FilterQuery) GetToBlock() *BigInt      { return &BigInt{fq.query.ToBlock} } | ||||||
|  | func (fq *FilterQuery) GetAddresses() *Addresses { return &Addresses{fq.query.Addresses} } | ||||||
|  | func (fq *FilterQuery) GetTopics() *Topics       { return &Topics{fq.query.Topics} } | ||||||
							
								
								
									
										188
									
								
								mobile/geth.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								mobile/geth.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains all the wrappers from the node package to support client side node | ||||||
|  | // management on mobile platforms. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"math/big" | ||||||
|  | 	"path/filepath" | ||||||
|  |  | ||||||
|  | 	"github.com/ethereum/go-ethereum/cmd/utils" | ||||||
|  | 	"github.com/ethereum/go-ethereum/common" | ||||||
|  | 	"github.com/ethereum/go-ethereum/core" | ||||||
|  | 	"github.com/ethereum/go-ethereum/core/state" | ||||||
|  | 	"github.com/ethereum/go-ethereum/eth" | ||||||
|  | 	"github.com/ethereum/go-ethereum/ethclient" | ||||||
|  | 	"github.com/ethereum/go-ethereum/node" | ||||||
|  | 	"github.com/ethereum/go-ethereum/p2p/nat" | ||||||
|  | 	"github.com/ethereum/go-ethereum/whisper" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // NodeConfig represents the collection of configuration values to fine tune the Geth | ||||||
|  | // node embedded into a mobile process. The available values are a subset of the | ||||||
|  | // entire API provided by go-ethereum to reduce the maintenance surface and dev | ||||||
|  | // complexity. | ||||||
|  | type NodeConfig struct { | ||||||
|  | 	// Bootstrap nodes used to establish connectivity with the rest of the network. | ||||||
|  | 	BootstrapNodes *Enodes | ||||||
|  |  | ||||||
|  | 	// MaxPeers is the maximum number of peers that can be connected. If this is | ||||||
|  | 	// set to zero, then only the configured static and trusted peers can connect. | ||||||
|  | 	MaxPeers int | ||||||
|  |  | ||||||
|  | 	// EthereumEnabled specifies whether the node should run the Ethereum protocol. | ||||||
|  | 	EthereumEnabled bool | ||||||
|  |  | ||||||
|  | 	// EthereumNetworkID is the network identifier used by the Ethereum protocol to | ||||||
|  | 	// decide if remote peers should be accepted or not. | ||||||
|  | 	EthereumNetworkID int | ||||||
|  |  | ||||||
|  | 	// EthereumChainConfig is the default parameters of the blockchain to use. If no | ||||||
|  | 	// configuration is specified, it defaults to the main network. | ||||||
|  | 	EthereumChainConfig *ChainConfig | ||||||
|  |  | ||||||
|  | 	// EthereumGenesis is the genesis JSON to use to seed the blockchain with. An | ||||||
|  | 	// empty genesis state is equivalent to using the mainnet's state. | ||||||
|  | 	EthereumGenesis string | ||||||
|  |  | ||||||
|  | 	// EthereumTestnetNonces specifies whether to use account nonces from the testnet | ||||||
|  | 	// range (2^20) or from the mainnet one (0). | ||||||
|  | 	EthereumTestnetNonces bool | ||||||
|  |  | ||||||
|  | 	// EthereumDatabaseCache is the system memory in MB to allocate for database caching. | ||||||
|  | 	// A minimum of 16MB is always reserved. | ||||||
|  | 	EthereumDatabaseCache int | ||||||
|  |  | ||||||
|  | 	// WhisperEnabled specifies whether the node should run the Whisper protocol. | ||||||
|  | 	WhisperEnabled bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // defaultNodeConfig contains the default node configuration values to use if all | ||||||
|  | // or some fields are missing from the user's specified list. | ||||||
|  | var defaultNodeConfig = &NodeConfig{ | ||||||
|  | 	BootstrapNodes:        MainnetBootnodes(), | ||||||
|  | 	MaxPeers:              25, | ||||||
|  | 	EthereumEnabled:       true, | ||||||
|  | 	EthereumNetworkID:     1, | ||||||
|  | 	EthereumChainConfig:   MainnetChainConfig, | ||||||
|  | 	EthereumDatabaseCache: 16, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewNodeConfig creates a new node option set, initialized to the default values. | ||||||
|  | func NewNodeConfig() *NodeConfig { | ||||||
|  | 	config := *defaultNodeConfig | ||||||
|  | 	return &config | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Node represents a Geth Ethereum node instance. | ||||||
|  | type Node struct { | ||||||
|  | 	node *node.Node | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewNode creates and configures a new Geth node. | ||||||
|  | func NewNode(datadir string, config *NodeConfig) (*Node, error) { | ||||||
|  | 	// If no or partial configurations were specified, use defaults | ||||||
|  | 	if config == nil { | ||||||
|  | 		config = NewNodeConfig() | ||||||
|  | 	} | ||||||
|  | 	if config.MaxPeers == 0 { | ||||||
|  | 		config.MaxPeers = defaultNodeConfig.MaxPeers | ||||||
|  | 	} | ||||||
|  | 	// Create the empty networking stack | ||||||
|  | 	nodeConf := &node.Config{ | ||||||
|  | 		DataDir:        datadir, | ||||||
|  | 		KeyStoreDir:    filepath.Join(datadir, "keystore"), // Mobile should never use internal keystores! | ||||||
|  | 		Name:           common.MakeName(clientIdentifier, utils.Version), | ||||||
|  | 		BootstrapNodes: config.BootstrapNodes.nodes, | ||||||
|  | 		ListenAddr:     ":0", | ||||||
|  | 		NAT:            nat.Any(), | ||||||
|  | 		MaxPeers:       config.MaxPeers, | ||||||
|  | 	} | ||||||
|  | 	stack, err := node.New(nodeConf) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	// Register the Ethereum protocol if requested | ||||||
|  | 	if config.EthereumEnabled { | ||||||
|  | 		ethConf := ð.Config{ | ||||||
|  | 			ChainConfig: &core.ChainConfig{ | ||||||
|  | 				HomesteadBlock: big.NewInt(config.EthereumChainConfig.HomesteadBlock), | ||||||
|  | 				DAOForkBlock:   big.NewInt(config.EthereumChainConfig.DAOForkBlock), | ||||||
|  | 				DAOForkSupport: config.EthereumChainConfig.DAOForkSupport, | ||||||
|  | 			}, | ||||||
|  | 			Genesis:                 config.EthereumGenesis, | ||||||
|  | 			FastSync:                true, | ||||||
|  | 			DatabaseCache:           config.EthereumDatabaseCache, | ||||||
|  | 			NetworkId:               config.EthereumNetworkID, | ||||||
|  | 			GasPrice:                new(big.Int).Mul(big.NewInt(20), common.Shannon), | ||||||
|  | 			GpoMinGasPrice:          new(big.Int).Mul(big.NewInt(20), common.Shannon), | ||||||
|  | 			GpoMaxGasPrice:          new(big.Int).Mul(big.NewInt(500), common.Shannon), | ||||||
|  | 			GpoFullBlockRatio:       80, | ||||||
|  | 			GpobaseStepDown:         10, | ||||||
|  | 			GpobaseStepUp:           100, | ||||||
|  | 			GpobaseCorrectionFactor: 110, | ||||||
|  | 		} | ||||||
|  | 		if config.EthereumTestnetNonces { | ||||||
|  | 			state.StartingNonce = 1048576 // (2**20) | ||||||
|  | 		} | ||||||
|  | 		if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { | ||||||
|  | 			return eth.New(ctx, ethConf) | ||||||
|  | 		}); err != nil { | ||||||
|  | 			return nil, fmt.Errorf("ethereum init: %v", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	// Register the Whisper protocol if requested | ||||||
|  | 	if config.WhisperEnabled { | ||||||
|  | 		if err := stack.Register(func(*node.ServiceContext) (node.Service, error) { return whisper.New(), nil }); err != nil { | ||||||
|  | 			return nil, fmt.Errorf("whisper init: %v", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return &Node{stack}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Start creates a live P2P node and starts running it. | ||||||
|  | func (n *Node) Start() error { | ||||||
|  | 	return n.node.Start() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Stop terminates a running node along with all it's services. In the node was | ||||||
|  | // not started, an error is returned. | ||||||
|  | func (n *Node) Stop() error { | ||||||
|  | 	return n.node.Stop() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetEthereumClient retrieves a client to access the Ethereum subsystem. | ||||||
|  | func (n *Node) GetEthereumClient() (*EthereumClient, error) { | ||||||
|  | 	rpc, err := n.node.Attach() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return &EthereumClient{ethclient.NewClient(rpc)}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetNodeInfo gathers and returns a collection of metadata known about the host. | ||||||
|  | func (n *Node) GetNodeInfo() *NodeInfo { | ||||||
|  | 	return &NodeInfo{n.node.Server().NodeInfo()} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetPeersInfo returns an array of metadata objects describing connected peers. | ||||||
|  | func (n *Node) GetPeersInfo() *PeerInfos { | ||||||
|  | 	return &PeerInfos{n.node.Server().PeersInfo()} | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								mobile/geth_android.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								mobile/geth_android.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // +build android | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | // clientIdentifier is a hard coded identifier to report into the network. | ||||||
|  | var clientIdentifier = "GethDroid" | ||||||
							
								
								
									
										22
									
								
								mobile/geth_ios.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								mobile/geth_ios.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // +build ios | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | // clientIdentifier is a hard coded identifier to report into the network. | ||||||
|  | var clientIdentifier = "iGeth" | ||||||
							
								
								
									
										22
									
								
								mobile/geth_other.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								mobile/geth_other.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // +build !android,!ios | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | // clientIdentifier is a hard coded identifier to report into the network. | ||||||
|  | var clientIdentifier = "GethMobile" | ||||||
							
								
								
									
										29
									
								
								mobile/glog.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								mobile/glog.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains wrappers and init code for the logger. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/ethereum/go-ethereum/logger" | ||||||
|  | 	"github.com/ethereum/go-ethereum/logger/glog" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func init() { | ||||||
|  | 	glog.SetV(logger.Info) | ||||||
|  | 	glog.SetToStderr(true) | ||||||
|  | } | ||||||
							
								
								
									
										148
									
								
								mobile/interface.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								mobile/interface.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains perverted wrappers to allow crossing over empty interfaces. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"math/big" | ||||||
|  |  | ||||||
|  | 	"github.com/ethereum/go-ethereum/common" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Interface represents a wrapped version of Go's interface{}, with the capacity | ||||||
|  | // to store arbitrary data types. | ||||||
|  | // | ||||||
|  | // Since it's impossible to get the arbitrary-ness converted between Go and mobile | ||||||
|  | // platforms, we're using explicit getters and setters for the conversions. There | ||||||
|  | // is of course no point in enumerating everything, just enough to support the | ||||||
|  | // contract bindins requiring client side generated code. | ||||||
|  | type Interface struct { | ||||||
|  | 	object interface{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewInterface creates a new empty interface that can be used to pass around | ||||||
|  | // generic types. | ||||||
|  | func NewInterface() *Interface { | ||||||
|  | 	return new(Interface) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (i *Interface) SetBool(b bool)                { i.object = &b } | ||||||
|  | func (i *Interface) SetBools(bs []bool)            { i.object = &bs } | ||||||
|  | func (i *Interface) SetString(str string)          { i.object = &str } | ||||||
|  | func (i *Interface) SetStrings(strs *Strings)      { i.object = &strs.strs } | ||||||
|  | func (i *Interface) SetBinary(binary []byte)       { i.object = &binary } | ||||||
|  | func (i *Interface) SetBinaries(binaries [][]byte) { i.object = &binaries } | ||||||
|  | func (i *Interface) SetAddress(address *Address)   { i.object = &address.address } | ||||||
|  | func (i *Interface) SetAddresses(addrs *Addresses) { i.object = &addrs.addresses } | ||||||
|  | func (i *Interface) SetHash(hash *Hash)            { i.object = &hash.hash } | ||||||
|  | func (i *Interface) SetHashes(hashes *Hashes)      { i.object = &hashes.hashes } | ||||||
|  | func (i *Interface) SetInt8(n int8)                { i.object = &n } | ||||||
|  | func (i *Interface) SetInt16(n int16)              { i.object = &n } | ||||||
|  | func (i *Interface) SetInt32(n int32)              { i.object = &n } | ||||||
|  | func (i *Interface) SetInt64(n int64)              { i.object = &n } | ||||||
|  | func (i *Interface) SetUint8(bigint *BigInt)       { n := uint8(bigint.bigint.Uint64()); i.object = &n } | ||||||
|  | func (i *Interface) SetUint16(bigint *BigInt)      { n := uint16(bigint.bigint.Uint64()); i.object = &n } | ||||||
|  | func (i *Interface) SetUint32(bigint *BigInt)      { n := uint32(bigint.bigint.Uint64()); i.object = &n } | ||||||
|  | func (i *Interface) SetUint64(bigint *BigInt)      { n := uint64(bigint.bigint.Uint64()); i.object = &n } | ||||||
|  | func (i *Interface) SetBigInt(bigint *BigInt)      { i.object = &bigint.bigint } | ||||||
|  | func (i *Interface) SetBigInts(bigints *BigInts)   { i.object = &bigints.bigints } | ||||||
|  |  | ||||||
|  | func (i *Interface) SetDefaultBool()      { i.object = new(bool) } | ||||||
|  | func (i *Interface) SetDefaultBools()     { i.object = new([]bool) } | ||||||
|  | func (i *Interface) SetDefaultString()    { i.object = new(string) } | ||||||
|  | func (i *Interface) SetDefaultStrings()   { i.object = new([]string) } | ||||||
|  | func (i *Interface) SetDefaultBinary()    { i.object = new([]byte) } | ||||||
|  | func (i *Interface) SetDefaultBinaries()  { i.object = new([][]byte) } | ||||||
|  | func (i *Interface) SetDefaultAddress()   { i.object = new(common.Address) } | ||||||
|  | func (i *Interface) SetDefaultAddresses() { i.object = new([]common.Address) } | ||||||
|  | func (i *Interface) SetDefaultHash()      { i.object = new(common.Hash) } | ||||||
|  | func (i *Interface) SetDefaultHashes()    { i.object = new([]common.Hash) } | ||||||
|  | func (i *Interface) SetDefaultInt8()      { i.object = new(int8) } | ||||||
|  | func (i *Interface) SetDefaultInt16()     { i.object = new(int16) } | ||||||
|  | func (i *Interface) SetDefaultInt32()     { i.object = new(int32) } | ||||||
|  | func (i *Interface) SetDefaultInt64()     { i.object = new(int64) } | ||||||
|  | func (i *Interface) SetDefaultUint8()     { i.object = new(uint8) } | ||||||
|  | func (i *Interface) SetDefaultUint16()    { i.object = new(uint16) } | ||||||
|  | func (i *Interface) SetDefaultUint32()    { i.object = new(uint32) } | ||||||
|  | func (i *Interface) SetDefaultUint64()    { i.object = new(uint64) } | ||||||
|  | func (i *Interface) SetDefaultBigInt()    { i.object = new(*big.Int) } | ||||||
|  | func (i *Interface) SetDefaultBigInts()   { i.object = new([]*big.Int) } | ||||||
|  |  | ||||||
|  | func (i *Interface) GetBool() bool            { return *i.object.(*bool) } | ||||||
|  | func (i *Interface) GetBools() []bool         { return *i.object.(*[]bool) } | ||||||
|  | func (i *Interface) GetString() string        { return *i.object.(*string) } | ||||||
|  | func (i *Interface) GetStrings() *Strings     { return &Strings{*i.object.(*[]string)} } | ||||||
|  | func (i *Interface) GetBinary() []byte        { return *i.object.(*[]byte) } | ||||||
|  | func (i *Interface) GetBinaries() [][]byte    { return *i.object.(*[][]byte) } | ||||||
|  | func (i *Interface) GetAddress() *Address     { return &Address{*i.object.(*common.Address)} } | ||||||
|  | func (i *Interface) GetAddresses() *Addresses { return &Addresses{*i.object.(*[]common.Address)} } | ||||||
|  | func (i *Interface) GetHash() *Hash           { return &Hash{*i.object.(*common.Hash)} } | ||||||
|  | func (i *Interface) GetHashes() *Hashes       { return &Hashes{*i.object.(*[]common.Hash)} } | ||||||
|  | func (i *Interface) GetInt8() int8            { return *i.object.(*int8) } | ||||||
|  | func (i *Interface) GetInt16() int16          { return *i.object.(*int16) } | ||||||
|  | func (i *Interface) GetInt32() int32          { return *i.object.(*int32) } | ||||||
|  | func (i *Interface) GetInt64() int64          { return *i.object.(*int64) } | ||||||
|  | func (i *Interface) GetUint8() *BigInt { | ||||||
|  | 	return &BigInt{new(big.Int).SetUint64(uint64(*i.object.(*uint8)))} | ||||||
|  | } | ||||||
|  | func (i *Interface) GetUint16() *BigInt { | ||||||
|  | 	return &BigInt{new(big.Int).SetUint64(uint64(*i.object.(*uint16)))} | ||||||
|  | } | ||||||
|  | func (i *Interface) GetUint32() *BigInt { | ||||||
|  | 	return &BigInt{new(big.Int).SetUint64(uint64(*i.object.(*uint32)))} | ||||||
|  | } | ||||||
|  | func (i *Interface) GetUint64() *BigInt { | ||||||
|  | 	return &BigInt{new(big.Int).SetUint64(*i.object.(*uint64))} | ||||||
|  | } | ||||||
|  | func (i *Interface) GetBigInt() *BigInt   { return &BigInt{*i.object.(**big.Int)} } | ||||||
|  | func (i *Interface) GetBigInts() *BigInts { return &BigInts{*i.object.(*[]*big.Int)} } | ||||||
|  |  | ||||||
|  | // Interfaces is a slices of wrapped generic objects. | ||||||
|  | type Interfaces struct { | ||||||
|  | 	objects []interface{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewInterfaces creates a slice of uninitialized interfaces. | ||||||
|  | func NewInterfaces(size int) *Interfaces { | ||||||
|  | 	return &Interfaces{ | ||||||
|  | 		objects: make([]interface{}, size), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Size returns the number of interfaces in the slice. | ||||||
|  | func (i *Interfaces) Size() int { | ||||||
|  | 	return len(i.objects) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the bigint at the given index from the slice. | ||||||
|  | func (i *Interfaces) Get(index int) (*Interface, error) { | ||||||
|  | 	if index < 0 || index >= len(i.objects) { | ||||||
|  | 		return nil, errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	return &Interface{i.objects[index]}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Set sets the big int at the given index in the slice. | ||||||
|  | func (i *Interfaces) Set(index int, object *Interface) error { | ||||||
|  | 	if index < 0 || index >= len(i.objects) { | ||||||
|  | 		return errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	i.objects[index] = object.object | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										74
									
								
								mobile/p2p.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								mobile/p2p.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received pi copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains wrappers for the p2p package. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  |  | ||||||
|  | 	"github.com/ethereum/go-ethereum/p2p" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // NodeInfo represents pi short summary of the information known about the host. | ||||||
|  | type NodeInfo struct { | ||||||
|  | 	info *p2p.NodeInfo | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (ni *NodeInfo) GetID() string              { return ni.info.ID } | ||||||
|  | func (ni *NodeInfo) GetName() string            { return ni.info.Name } | ||||||
|  | func (ni *NodeInfo) GetEnode() string           { return ni.info.Enode } | ||||||
|  | func (ni *NodeInfo) GetIP() string              { return ni.info.IP } | ||||||
|  | func (ni *NodeInfo) GetDiscoveryPort() int      { return ni.info.Ports.Discovery } | ||||||
|  | func (ni *NodeInfo) GetListenerPort() int       { return ni.info.Ports.Listener } | ||||||
|  | func (ni *NodeInfo) GetListenerAddress() string { return ni.info.ListenAddr } | ||||||
|  | func (ni *NodeInfo) GetProtocols() *Strings { | ||||||
|  | 	protos := []string{} | ||||||
|  | 	for proto, _ := range ni.info.Protocols { | ||||||
|  | 		protos = append(protos, proto) | ||||||
|  | 	} | ||||||
|  | 	return &Strings{protos} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // PeerInfo represents pi short summary of the information known about pi connected peer. | ||||||
|  | type PeerInfo struct { | ||||||
|  | 	info *p2p.PeerInfo | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (pi *PeerInfo) GetID() string            { return pi.info.ID } | ||||||
|  | func (pi *PeerInfo) GetName() string          { return pi.info.Name } | ||||||
|  | func (pi *PeerInfo) GetCaps() *Strings        { return &Strings{pi.info.Caps} } | ||||||
|  | func (pi *PeerInfo) GetLocalAddress() string  { return pi.info.Network.LocalAddress } | ||||||
|  | func (pi *PeerInfo) GetRemoteAddress() string { return pi.info.Network.RemoteAddress } | ||||||
|  |  | ||||||
|  | // PeerInfos represents a slice of infos about remote peers. | ||||||
|  | type PeerInfos struct { | ||||||
|  | 	infos []*p2p.PeerInfo | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Size returns the number of peer info entries in the slice. | ||||||
|  | func (pi *PeerInfos) Size() int { | ||||||
|  | 	return len(pi.infos) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the peer info at the given index from the slice. | ||||||
|  | func (pi *PeerInfos) Get(index int) (*PeerInfo, error) { | ||||||
|  | 	if index < 0 || index >= len(pi.infos) { | ||||||
|  | 		return nil, errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	return &PeerInfo{pi.infos[index]}, nil | ||||||
|  | } | ||||||
							
								
								
									
										54
									
								
								mobile/primitives.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								mobile/primitives.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received s copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains various wrappers for primitive types. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Strings represents s slice of strs. | ||||||
|  | type Strings struct{ strs []string } | ||||||
|  |  | ||||||
|  | // Size returns the number of strs in the slice. | ||||||
|  | func (s *Strings) Size() int { | ||||||
|  | 	return len(s.strs) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the string at the given index from the slice. | ||||||
|  | func (s *Strings) Get(index int) (string, error) { | ||||||
|  | 	if index < 0 || index >= len(s.strs) { | ||||||
|  | 		return "", errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	return s.strs[index], nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Set sets the string at the given index in the slice. | ||||||
|  | func (s *Strings) Set(index int, str string) error { | ||||||
|  | 	if index < 0 || index >= len(s.strs) { | ||||||
|  | 		return errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	s.strs[index] = str | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String implements the Stringer interface. | ||||||
|  | func (s *Strings) String() string { | ||||||
|  | 	return fmt.Sprintf("%v", s.strs) | ||||||
|  | } | ||||||
							
								
								
									
										189
									
								
								mobile/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								mobile/types.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,189 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains all the wrappers from the core/types package. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  |  | ||||||
|  | 	"github.com/ethereum/go-ethereum/core/types" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // A Nonce is a 64-bit hash which proves (combined with the mix-hash) that | ||||||
|  | // a sufficient amount of computation has been carried out on a block. | ||||||
|  | type Nonce struct { | ||||||
|  | 	nonce types.BlockNonce | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetBytes retrieves the byte representation of the block nonce. | ||||||
|  | func (n *Nonce) GetBytes() []byte { | ||||||
|  | 	return n.nonce[:] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetHex retrieves the hex string representation of the block nonce. | ||||||
|  | func (n *Nonce) GetHex() string { | ||||||
|  | 	return fmt.Sprintf("0x%x", n.nonce[:]) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Bloom represents a 256 bit bloom filter. | ||||||
|  | type Bloom struct { | ||||||
|  | 	bloom types.Bloom | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetBytes retrieves the byte representation of the bloom filter. | ||||||
|  | func (b *Bloom) GetBytes() []byte { | ||||||
|  | 	return b.bloom[:] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetHex retrieves the hex string representation of the bloom filter. | ||||||
|  | func (b *Bloom) GetHex() string { | ||||||
|  | 	return fmt.Sprintf("0x%x", b.bloom[:]) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Header represents a block header in the Ethereum blockchain. | ||||||
|  | type Header struct { | ||||||
|  | 	header *types.Header | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (h *Header) GetParentHash() *Hash   { return &Hash{h.header.ParentHash} } | ||||||
|  | func (h *Header) GetUncleHash() *Hash    { return &Hash{h.header.UncleHash} } | ||||||
|  | func (h *Header) GetCoinbase() *Address  { return &Address{h.header.Coinbase} } | ||||||
|  | func (h *Header) GetRoot() *Hash         { return &Hash{h.header.Root} } | ||||||
|  | func (h *Header) GetTxHash() *Hash       { return &Hash{h.header.TxHash} } | ||||||
|  | func (h *Header) GetReceiptHash() *Hash  { return &Hash{h.header.ReceiptHash} } | ||||||
|  | func (h *Header) GetBloom() *Bloom       { return &Bloom{h.header.Bloom} } | ||||||
|  | func (h *Header) GetDifficulty() *BigInt { return &BigInt{h.header.Difficulty} } | ||||||
|  | func (h *Header) GetNumber() int64       { return h.header.Number.Int64() } | ||||||
|  | func (h *Header) GetGasLimit() int64     { return h.header.GasLimit.Int64() } | ||||||
|  | func (h *Header) GetGasUsed() int64      { return h.header.GasUsed.Int64() } | ||||||
|  | func (h *Header) GetTime() int64         { return h.header.Time.Int64() } | ||||||
|  | func (h *Header) GetExtra() []byte       { return h.header.Extra } | ||||||
|  | func (h *Header) GetMixDigest() *Hash    { return &Hash{h.header.MixDigest} } | ||||||
|  | func (h *Header) GetNonce() *Nonce       { return &Nonce{h.header.Nonce} } | ||||||
|  |  | ||||||
|  | func (h *Header) GetHash() *Hash        { return &Hash{h.header.Hash()} } | ||||||
|  | func (h *Header) GetHashNoNonce() *Hash { return &Hash{h.header.HashNoNonce()} } | ||||||
|  |  | ||||||
|  | // Headers represents a slice of headers. | ||||||
|  | type Headers struct{ headers []*types.Header } | ||||||
|  |  | ||||||
|  | // Size returns the number of headers in the slice. | ||||||
|  | func (h *Headers) Size() int { | ||||||
|  | 	return len(h.headers) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the header at the given index from the slice. | ||||||
|  | func (h *Headers) Get(index int) (*Header, error) { | ||||||
|  | 	if index < 0 || index >= len(h.headers) { | ||||||
|  | 		return nil, errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	return &Header{h.headers[index]}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Block represents an entire block in the Ethereum blockchain. | ||||||
|  | type Block struct { | ||||||
|  | 	block *types.Block | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (b *Block) GetParentHash() *Hash   { return &Hash{b.block.ParentHash()} } | ||||||
|  | func (b *Block) GetUncleHash() *Hash    { return &Hash{b.block.UncleHash()} } | ||||||
|  | func (b *Block) GetCoinbase() *Address  { return &Address{b.block.Coinbase()} } | ||||||
|  | func (b *Block) GetRoot() *Hash         { return &Hash{b.block.Root()} } | ||||||
|  | func (b *Block) GetTxHash() *Hash       { return &Hash{b.block.TxHash()} } | ||||||
|  | func (b *Block) GetReceiptHash() *Hash  { return &Hash{b.block.ReceiptHash()} } | ||||||
|  | func (b *Block) GetBloom() *Bloom       { return &Bloom{b.block.Bloom()} } | ||||||
|  | func (b *Block) GetDifficulty() *BigInt { return &BigInt{b.block.Difficulty()} } | ||||||
|  | func (b *Block) GetNumber() int64       { return b.block.Number().Int64() } | ||||||
|  | func (b *Block) GetGasLimit() int64     { return b.block.GasLimit().Int64() } | ||||||
|  | func (b *Block) GetGasUsed() int64      { return b.block.GasUsed().Int64() } | ||||||
|  | func (b *Block) GetTime() int64         { return b.block.Time().Int64() } | ||||||
|  | func (b *Block) GetExtra() []byte       { return b.block.Extra() } | ||||||
|  | func (b *Block) GetMixDigest() *Hash    { return &Hash{b.block.MixDigest()} } | ||||||
|  | func (b *Block) GetNonce() int64        { return int64(b.block.Nonce()) } | ||||||
|  |  | ||||||
|  | func (b *Block) GetHash() *Hash        { return &Hash{b.block.Hash()} } | ||||||
|  | func (b *Block) GetHashNoNonce() *Hash { return &Hash{b.block.HashNoNonce()} } | ||||||
|  |  | ||||||
|  | func (b *Block) GetHeader() *Header             { return &Header{b.block.Header()} } | ||||||
|  | func (b *Block) GetUncles() *Headers            { return &Headers{b.block.Uncles()} } | ||||||
|  | func (b *Block) GetTransactions() *Transactions { return &Transactions{b.block.Transactions()} } | ||||||
|  | func (b *Block) GetTransaction(hash *Hash) *Transaction { | ||||||
|  | 	return &Transaction{b.block.Transaction(hash.hash)} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Transaction represents a single Ethereum transaction. | ||||||
|  | type Transaction struct { | ||||||
|  | 	tx *types.Transaction | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (tx *Transaction) GetData() []byte      { return tx.tx.Data() } | ||||||
|  | func (tx *Transaction) GetGas() int64        { return tx.tx.Gas().Int64() } | ||||||
|  | func (tx *Transaction) GetGasPrice() *BigInt { return &BigInt{tx.tx.GasPrice()} } | ||||||
|  | func (tx *Transaction) GetValue() *BigInt    { return &BigInt{tx.tx.Value()} } | ||||||
|  | func (tx *Transaction) GetNonce() int64      { return int64(tx.tx.Nonce()) } | ||||||
|  |  | ||||||
|  | func (tx *Transaction) GetHash() *Hash    { return &Hash{tx.tx.Hash()} } | ||||||
|  | func (tx *Transaction) GetSigHash() *Hash { return &Hash{tx.tx.SigHash()} } | ||||||
|  | func (tx *Transaction) GetCost() *BigInt  { return &BigInt{tx.tx.Cost()} } | ||||||
|  |  | ||||||
|  | func (tx *Transaction) GetFrom() (*Address, error) { | ||||||
|  | 	from, err := tx.tx.From() | ||||||
|  | 	return &Address{from}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (tx *Transaction) GetTo() *Address { | ||||||
|  | 	if to := tx.tx.To(); to != nil { | ||||||
|  | 		return &Address{*to} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (tx *Transaction) WithSignature(sig []byte) (*Transaction, error) { | ||||||
|  | 	t, err := tx.tx.WithSignature(sig) | ||||||
|  | 	return &Transaction{t}, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Transactions represents a slice of transactions. | ||||||
|  | type Transactions struct{ txs types.Transactions } | ||||||
|  |  | ||||||
|  | // Size returns the number of transactions in the slice. | ||||||
|  | func (t *Transactions) Size() int { | ||||||
|  | 	return len(t.txs) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the transaction at the given index from the slice. | ||||||
|  | func (t *Transactions) Get(index int) (*Transaction, error) { | ||||||
|  | 	if index < 0 || index >= len(t.txs) { | ||||||
|  | 		return nil, errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	return &Transaction{t.txs[index]}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Receipt represents the results of a transaction. | ||||||
|  | type Receipt struct { | ||||||
|  | 	receipt *types.Receipt | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *Receipt) GetPostState() []byte          { return r.receipt.PostState } | ||||||
|  | func (r *Receipt) GetCumulativeGasUsed() *BigInt { return &BigInt{r.receipt.CumulativeGasUsed} } | ||||||
|  | func (r *Receipt) GetBloom() *Bloom              { return &Bloom{r.receipt.Bloom} } | ||||||
|  | func (r *Receipt) GetLogs() *Logs                { return &Logs{r.receipt.Logs} } | ||||||
|  | func (r *Receipt) GetTxHash() *Hash              { return &Hash{r.receipt.TxHash} } | ||||||
|  | func (r *Receipt) GetContractAddress() *Address  { return &Address{r.receipt.ContractAddress} } | ||||||
|  | func (r *Receipt) GetGasUsed() *BigInt           { return &BigInt{r.receipt.GasUsed} } | ||||||
							
								
								
									
										56
									
								
								mobile/vm.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								mobile/vm.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | |||||||
|  | // Copyright 2016 The go-ethereum Authors | ||||||
|  | // This file is part of the go-ethereum library. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU Lesser General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | // Contains all the wrappers from the core/types package. | ||||||
|  |  | ||||||
|  | package geth | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  |  | ||||||
|  | 	"github.com/ethereum/go-ethereum/core/vm" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Log represents a contract log event. These events are generated by the LOG | ||||||
|  | // opcode and stored/indexed by the node. | ||||||
|  | type Log struct { | ||||||
|  | 	log *vm.Log | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (l *Log) GetAddress() *Address  { return &Address{l.log.Address} } | ||||||
|  | func (l *Log) GetTopics() *Hashes    { return &Hashes{l.log.Topics} } | ||||||
|  | func (l *Log) GetData() []byte       { return l.log.Data } | ||||||
|  | func (l *Log) GetBlockNumber() int64 { return int64(l.log.BlockNumber) } | ||||||
|  | func (l *Log) GetTxHash() *Hash      { return &Hash{l.log.TxHash} } | ||||||
|  | func (l *Log) GetTxIndex() int       { return int(l.log.TxIndex) } | ||||||
|  | func (l *Log) GetBlockHash() *Hash   { return &Hash{l.log.BlockHash} } | ||||||
|  | func (l *Log) GetIndex() int         { return int(l.log.Index) } | ||||||
|  |  | ||||||
|  | // Logs represents a slice of VM logs. | ||||||
|  | type Logs struct{ logs vm.Logs } | ||||||
|  |  | ||||||
|  | // Size returns the number of logs in the slice. | ||||||
|  | func (l *Logs) Size() int { | ||||||
|  | 	return len(l.logs) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the log at the given index from the slice. | ||||||
|  | func (l *Logs) Get(index int) (*Log, error) { | ||||||
|  | 	if index < 0 || index >= len(l.logs) { | ||||||
|  | 		return nil, errors.New("index out of bounds") | ||||||
|  | 	} | ||||||
|  | 	return &Log{l.logs[index]}, nil | ||||||
|  | } | ||||||
| @@ -35,7 +35,7 @@ import ( | |||||||
| 	"github.com/ethereum/go-ethereum/crypto/secp256k1" | 	"github.com/ethereum/go-ethereum/crypto/secp256k1" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const nodeIDBits = 512 | const NodeIDBits = 512 | ||||||
|  |  | ||||||
| // Node represents a host on the network. | // Node represents a host on the network. | ||||||
| // The fields of Node may not be modified. | // The fields of Node may not be modified. | ||||||
| @@ -209,7 +209,7 @@ func MustParseNode(rawurl string) *Node { | |||||||
|  |  | ||||||
| // NodeID is a unique identifier for each node. | // NodeID is a unique identifier for each node. | ||||||
| // The node identifier is a marshaled elliptic curve public key. | // The node identifier is a marshaled elliptic curve public key. | ||||||
| type NodeID [nodeIDBits / 8]byte | type NodeID [NodeIDBits / 8]byte | ||||||
|  |  | ||||||
| // NodeID prints as a long hexadecimal number. | // NodeID prints as a long hexadecimal number. | ||||||
| func (n NodeID) String() string { | func (n NodeID) String() string { | ||||||
|   | |||||||
| @@ -748,7 +748,7 @@ type NodeInfo struct { | |||||||
| 	Protocols  map[string]interface{} `json:"protocols"` | 	Protocols  map[string]interface{} `json:"protocols"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // Info gathers and returns a collection of metadata known about the host. | // NodeInfo gathers and returns a collection of metadata known about the host. | ||||||
| func (srv *Server) NodeInfo() *NodeInfo { | func (srv *Server) NodeInfo() *NodeInfo { | ||||||
| 	node := srv.Self() | 	node := srv.Self() | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user