Revert "Move wiki pages to github pages (#18497)"
This reverts commit 40eb803de1
.
This commit is contained in:
@ -1,34 +0,0 @@
|
||||
---
|
||||
title: Active go-ethereum projects
|
||||
---
|
||||
## Direction of development until the end of 2018
|
||||
|
||||
- Clef: move account management out of geth to clef
|
||||
- Constantinople - Tools for testing
|
||||
- Automate cross-client testing
|
||||
- Progpow (ASIC-resistent PoW algorithm)
|
||||
- Ethereum Node Report
|
||||
- Topic discovery
|
||||
- Build an end-to-end test system
|
||||
- Simple API for LES-protocol
|
||||
- Loadbalance tests using Swarm team's network simulator
|
||||
- Test FlowControl subsystem rewrite
|
||||
- Clients get more bandwidth with micro-payment
|
||||
- Database IO reductions
|
||||
- Historical state pruning
|
||||
- Next gen sync algo (cross client)
|
||||
- Blockscout for Puppeth
|
||||
- Contract based signers for Clique (v1.5)
|
||||
- Rinkeby - improve maintenance
|
||||
- Concurrent tx execution experiment
|
||||
- Dashboard
|
||||
- Hive - Devp2p basic tests running as Hive simulation
|
||||
- Hive - Devp2p network tests (different clients peering)
|
||||
- Hive - Add all known client implementations
|
||||
- Hive - Public metrics/test failures page
|
||||
- DevP2P - Document protocols
|
||||
- Hive - Further tests for networked consensus
|
||||
- Discovery - Work with Felix to get ENR/next discovery out asap
|
||||
- Countable trie experiment - For better sync statistic and futher storage rent
|
||||
- Build an end-to-end test system
|
||||
- Finalize simple checkpoint syncing
|
@ -1,441 +0,0 @@
|
||||
---
|
||||
title: Native DApps / Go bindings to Ethereum contracts
|
||||
---
|
||||
**[Please note, events are not yet implemented as they need some RPC subscription
|
||||
features that are still under review.]**
|
||||
|
||||
The original roadmap and/or dream of the Ethereum platform was to provide a solid, high
|
||||
performing client implementation of the consensus protocol in various languages, which
|
||||
would provide an RPC interface for JavaScript DApps to communicate with, pushing towards
|
||||
the direction of the Mist browser, through which users can interact with the blockchain.
|
||||
|
||||
Although this was a solid plan for mainstream adoption and does cover quite a lot of use
|
||||
cases that people come up with (mostly where people manually interact with the blockchain),
|
||||
it eludes the server side (backend, fully automated, devops) use cases where JavaScript is
|
||||
usually not the language of choice given its dynamic nature.
|
||||
|
||||
This page introduces the concept of server side native Dapps: Go language bindings to any
|
||||
Ethereum contract that is compile time type safe, highly performant and best of all, can
|
||||
be generated fully automatically from a contract ABI and optionally the EVM bytecode.
|
||||
|
||||
*This page is written in a more beginner friendly tutorial style to make it easier for
|
||||
people to start out with writing Go native Dapps. The used concepts will be introduced
|
||||
gradually as a developer would need/encounter them. However, we do assume the reader
|
||||
is familiar with Ethereum in general, has a fair understanding of Solidity and can code
|
||||
Go.*
|
||||
|
||||
## Token contract
|
||||
|
||||
To avoid falling into the fallacy of useless academic examples, we're going to take the
|
||||
official [Token contract](https://ethereum.org/token) as the base for introducing the Go
|
||||
native bindings. If you're unfamiliar with the contract, skimming the linked page should
|
||||
probably be enough, the details aren't relevant for now. *In short the contract implements
|
||||
a custom token that can be deployed on top of Ethereum.* To make sure this tutorial doesn't
|
||||
go stale if the linked website changes, the Solidity source code of the Token contract is
|
||||
also available at [`token.sol`](https://gist.github.com/karalabe/08f4b780e01c8452d989).
|
||||
|
||||
### Go binding generator
|
||||
|
||||
Interacting with a contract on the Ethereum blockchain from Go (or any other language for
|
||||
a matter of fact) is already possible via the RPC interfaces exposed by Ethereum clients.
|
||||
However, writing the boilerplate code that translates decent Go language constructs into
|
||||
RPC calls and back is extremely time consuming and also extremely brittle: implementation
|
||||
bugs can only be detected during runtime and it's almost impossible to evolve a contract
|
||||
as even a tiny change in Solidity can be painful to port over to Go.
|
||||
|
||||
To avoid all this mess, the go-ethereum implementation introduces a source code generator
|
||||
that can convert Ethereum ABI definitions into easy to use, type-safe Go packages. Assuming
|
||||
you have a valid Go development environment set up, `godep` installed and the go-ethereum
|
||||
repository checked out correctly, you can build the generator with:
|
||||
|
||||
```
|
||||
$ cd $GOPATH/src/github.com/ethereum/go-ethereum
|
||||
$ godep go install ./cmd/abigen
|
||||
```
|
||||
|
||||
### Generating the bindings
|
||||
|
||||
The single essential thing needed to generate a Go binding to an Ethereum contract is the
|
||||
contract's ABI definition `JSON` file. For our `Token` contract tutorial you can obtain this
|
||||
either by compiling the Solidity code yourself (e.g. via @chriseth's [online Solidity compiler](https://chriseth.github.io/browser-solidity/)), or you can download our pre-compiled [`token.abi`](https://gist.github.com/karalabe/b8dfdb6d301660f56c1b).
|
||||
|
||||
To generate a binding, simply call:
|
||||
|
||||
```
|
||||
$ abigen --abi token.abi --pkg main --type Token --out token.go
|
||||
```
|
||||
|
||||
Where the flags are:
|
||||
|
||||
* `--abi`: Mandatory path to the contract ABI to bind to
|
||||
* `--pgk`: Mandatory Go package name to place the Go code into
|
||||
* `--type`: Optional Go type name to assign to the binding struct
|
||||
* `--out`: Optional output path for the generated Go source file (not set = stdout)
|
||||
|
||||
This will generate a type-safe Go binding for the Token contract. The generated code will
|
||||
look something like [`token.go`](https://gist.github.com/karalabe/5839509295afa4f7e2215bc4116c7a8f),
|
||||
but please generate your own as this will change as more work is put into the generator.
|
||||
|
||||
### Accessing an Ethereum contract
|
||||
|
||||
To interact with a contract deployed on the blockchain, you'll need to know the `address`
|
||||
of the contract itself, and need to specify a `backend` through which to access Ethereum.
|
||||
The binding generator provides out of the box an RPC backend through which you can attach
|
||||
to an existing Ethereum node via IPC, HTTP or WebSockets.
|
||||
|
||||
We'll use the foundation's [Unicorn](https://ethereum.org/donate) token contract deployed
|
||||
on the testnet to demonstrate calling contract methods. It is deployed at the address
|
||||
`0x21e6fc92f93c8a1bb41e2be64b4e1f88a54d3576`.
|
||||
|
||||
To run the snippet below, please ensure a Geth instance is running and attached to the
|
||||
Morden test network where the above mentioned contract was deployed. Also please update
|
||||
the path to the IPC socket below to the one reported by your own local Geth node.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Create an IPC based RPC connection to a remote node
|
||||
conn, err := ethclient.Dial("/home/karalabe/.ethereum/testnet/geth.ipc")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to connect to the Ethereum client: %v", err)
|
||||
}
|
||||
// Instantiate the contract and display its name
|
||||
token, err := NewToken(common.HexToAddress("0x21e6fc92f93c8a1bb41e2be64b4e1f88a54d3576"), conn)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to instantiate a Token contract: %v", err)
|
||||
}
|
||||
name, err := token.Name(nil)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to retrieve token name: %v", err)
|
||||
}
|
||||
fmt.Println("Token name:", name)
|
||||
}
|
||||
```
|
||||
|
||||
And the output (yay):
|
||||
|
||||
```
|
||||
Token name: Testnet Unicorn
|
||||
```
|
||||
|
||||
If you look at the method invoked to read the token name `token.Name(nil)`, it required
|
||||
a parameter to be passed, even though the original Solidity contract requires none. This
|
||||
is a `*bind.CallOpts` type, which can be used to fine tune the call.
|
||||
|
||||
* `Pending`: Whether to access pending contract state or the current stable one
|
||||
* `GasLimit`: Place a limit on the computing resources the call might consume
|
||||
|
||||
### Transacting with an Ethereum contract
|
||||
|
||||
Invoking a method that changes contract state (i.e. transacting) is a bit more involved,
|
||||
as a live transaction needs to be authorized and broadcast into the network. **Opposed
|
||||
to the conventional way of storing accounts and keys in the node we attach to, Go bindings
|
||||
require signing transactions locally and do not delegate this to a remote node.** This is
|
||||
done so to facilitate the general direction of the Ethereum community where accounts are
|
||||
kept private to DApps, and not shared (by default) between them.
|
||||
|
||||
Thus to allow transacting with a contract, your code needs to implement a method that
|
||||
given an input transaction, signs it and returns an authorized output transaction. Since
|
||||
most users have their keys in the [Web3 Secret Storage](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) format, the `bind` package contains a small utility method
|
||||
(`bind.NewTransactor(keyjson, passphrase)`) that can create an authorized transactor from
|
||||
a key file and associated password, without the user needing to implement key signing himself.
|
||||
|
||||
Changing the previous code snippet to send one unicorn to the zero address:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
)
|
||||
|
||||
const key = `paste the contents of your *testnet* key json here`
|
||||
|
||||
func main() {
|
||||
// Create an IPC based RPC connection to a remote node and instantiate a contract binding
|
||||
conn, err := ethclient.Dial("/home/karalabe/.ethereum/testnet/geth.ipc")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to connect to the Ethereum client: %v", err)
|
||||
}
|
||||
token, err := NewToken(common.HexToAddress("0x21e6fc92f93c8a1bb41e2be64b4e1f88a54d3576"), conn)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to instantiate a Token contract: %v", err)
|
||||
}
|
||||
// Create an authorized transactor and spend 1 unicorn
|
||||
auth, err := bind.NewTransactor(strings.NewReader(key), "my awesome super secret password")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create authorized transactor: %v", err)
|
||||
}
|
||||
tx, err := token.Transfer(auth, common.HexToAddress("0x0000000000000000000000000000000000000000"), big.NewInt(1))
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to request token transfer: %v", err)
|
||||
}
|
||||
fmt.Printf("Transfer pending: 0x%x\n", tx.Hash())
|
||||
}
|
||||
```
|
||||
|
||||
And the output (yay):
|
||||
|
||||
```
|
||||
Transfer pending: 0x4f4aaeb29ed48e88dd653a81f0b05d4df64a86c99d4e83b5bfeb0f0006b0e55b
|
||||
```
|
||||
|
||||
*Note, with high probability you won't have any testnet unicorns available to spend, so the
|
||||
above program will fail with an error. Send at least 2.014 testnet(!) Ethers to the foundation
|
||||
testnet tipjar `0xDf7D0030bfed998Db43288C190b63470c2d18F50` to receive a unicorn token and
|
||||
you'll be able to see the above code run without an error!*
|
||||
|
||||
Similar to the method invocations in the previous section which only read contract state,
|
||||
transacting methods also require a mandatory first parameter, a `*bind.TransactOpts` type,
|
||||
which authorizes the transaction and potentially fine tunes it:
|
||||
|
||||
* `From`: Address of the account to invoke the method with (mandatory)
|
||||
* `Signer`: Method to sign a transaction locally before broadcasting it (mandatory)
|
||||
* `Nonce`: Account nonce to use for the transaction ordering (optional)
|
||||
* `GasLimit`: Place a limit on the computing resources the call might consume (optional)
|
||||
* `GasPrice`: Explicitly set the gas price to run the transaction with (optional)
|
||||
* `Value`: Any funds to transfer along with the method call (optional)
|
||||
|
||||
The two mandatory fields are automatically set by the `bind` package if the auth options are
|
||||
constructed using `bind.NewTransactor`. The nonce and gas related fields are automatically
|
||||
derived by the binding if they are not set. An unset value is assumed to be zero.
|
||||
|
||||
### Pre-configured contract sessions
|
||||
|
||||
As mentioned in the previous two sections, both reading as well as state modifying contract
|
||||
calls require a mandatory first parameter which can both authorize as well as fine tune some
|
||||
of the internal parameters. However, most of the time we want to use the same parameters and
|
||||
issue transactions with the same account, so always constructing the call/transact options or
|
||||
passing them along with the binding can become unwieldy.
|
||||
|
||||
To avoid these scenarios, the generator also creates specialized wrappers that can be pre-
|
||||
configured with tuning and authorization parameters, allowing all the Solidity defined methods
|
||||
to be invoked without needing an extra parameter.
|
||||
|
||||
These are named analogous to the original contract type name, just suffixed with `Sessions`:
|
||||
|
||||
```go
|
||||
// Wrap the Token contract instance into a session
|
||||
session := &TokenSession{
|
||||
Contract: token,
|
||||
CallOpts: bind.CallOpts{
|
||||
Pending: true,
|
||||
},
|
||||
TransactOpts: bind.TransactOpts{
|
||||
From: auth.From,
|
||||
Signer: auth.Signer,
|
||||
GasLimit: big.NewInt(3141592),
|
||||
},
|
||||
}
|
||||
// Call the previous methods without the option parameters
|
||||
session.Name()
|
||||
session.Transfer("0x0000000000000000000000000000000000000000"), big.NewInt(1))
|
||||
```
|
||||
|
||||
### Deploying contracts to Ethereum
|
||||
|
||||
Interacting with existing contracts is nice, but let's take it up a notch and deploy
|
||||
a brand new contract onto the Ethereum blockchain! To do so however, the contract ABI
|
||||
we used to generate the binding is not enough. We need the compiled bytecode too to
|
||||
allow deploying it.
|
||||
|
||||
To get the bytecode, either go back to the online compiler with which you may generate it,
|
||||
or alternatively download our [`token.bin`](https://gist.github.com/karalabe/026548f6a5f5f97b54de).
|
||||
You'll need to rerun the Go generator with the bytecode included for it to create deploy
|
||||
code too:
|
||||
|
||||
```
|
||||
$ abigen --abi token.abi --pkg main --type Token --out token.go --bin token.bin
|
||||
```
|
||||
|
||||
This will generate something similar to [`token.go`](https://gist.github.com/karalabe/2153b087c1f80f651fd87dd4c439fac4).
|
||||
If you quickly skim this file, you'll find an extra `DeployToken` function that was just
|
||||
injected compared to the previous code. Beside all the parameters specified by Solidity,
|
||||
it also needs the usual authorization options to deploy the contract with and the Ethereum
|
||||
backend to deploy the contract through.
|
||||
|
||||
Putting it all together would result in:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
)
|
||||
|
||||
const key = `paste the contents of your *testnet* key json here`
|
||||
|
||||
func main() {
|
||||
// Create an IPC based RPC connection to a remote node and an authorized transactor
|
||||
conn, err := rpc.NewIPCClient("/home/karalabe/.ethereum/testnet/geth.ipc")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to connect to the Ethereum client: %v", err)
|
||||
}
|
||||
auth, err := bind.NewTransactor(strings.NewReader(key), "my awesome super secret password")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create authorized transactor: %v", err)
|
||||
}
|
||||
// Deploy a new awesome contract for the binding demo
|
||||
address, tx, token, err := DeployToken(auth, conn), new(big.Int), "Contracts in Go!!!", 0, "Go!")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to deploy new token contract: %v", err)
|
||||
}
|
||||
fmt.Printf("Contract pending deploy: 0x%x\n", address)
|
||||
fmt.Printf("Transaction waiting to be mined: 0x%x\n\n", tx.Hash())
|
||||
|
||||
// Don't even wait, check its presence in the local pending state
|
||||
time.Sleep(250 * time.Millisecond) // Allow it to be processed by the local node :P
|
||||
|
||||
name, err := token.Name(&bind.CallOpts{Pending: true})
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to retrieve pending name: %v", err)
|
||||
}
|
||||
fmt.Println("Pending name:", name)
|
||||
}
|
||||
```
|
||||
|
||||
And the code performs as expected: it requests the creation of a brand new Token contract
|
||||
on the Ethereum blockchain, which we can either wait for to be mined or as in the above code
|
||||
start calling methods on it in the pending state :)
|
||||
|
||||
```
|
||||
Contract pending deploy: 0x46506d900559ad005feb4645dcbb2dbbf65e19cc
|
||||
Transaction waiting to be mined: 0x6a81231874edd2461879b7280ddde1a857162a744e3658ca7ec276984802183b
|
||||
|
||||
Pending name: Contracts in Go!!!
|
||||
```
|
||||
|
||||
## Bind Solidity directly
|
||||
|
||||
If you've followed the tutorial along until this point you've probably realized that
|
||||
every contract modification needs to be recompiled, the produced ABIs and bytecodes
|
||||
(especially if you need multiple contracts) individually saved to files and then the
|
||||
binding executed for them. This can become a quite bothersome after the Nth iteration,
|
||||
so the `abigen` command supports binding from Solidity source files directly (`--sol`),
|
||||
which first compiles the source code (via `--solc`, defaulting to `solc`) into it's
|
||||
constituent components and binds using that.
|
||||
|
||||
Binding the official Token contract [`token.sol`](https://gist.github.com/karalabe/08f4b780e01c8452d989)
|
||||
would then entail to running:
|
||||
|
||||
```
|
||||
$ abigen --sol token.sol --pkg main --out token.go
|
||||
```
|
||||
|
||||
*Note: Building from Solidity (`--sol`) is mutually exclusive with individually setting
|
||||
the bind components (`--abi`, `--bin` and `--type`), as all of them are extracted from
|
||||
the Solidity code and produced build results directly.*
|
||||
|
||||
Building a contract directly from Solidity has the nice side effect that all contracts
|
||||
contained within a Solidity source file are built and bound, so if your file contains many
|
||||
contract sources, each and every one of them will be available from Go code. The sample
|
||||
Token solidity file results in [`token.go`](https://gist.github.com/karalabe/c22aab73194ba7da834ab5b379621031).
|
||||
|
||||
### Project integration (i.e. `go generate`)
|
||||
|
||||
The `abigen` command was made in such a way as to play beautifully together with existing
|
||||
Go toolchains: instead of having to remember the exact command needed to bind an Ethereum
|
||||
contract into a Go project, we can leverage `go generate` to remember all the nitty-gritty
|
||||
details.
|
||||
|
||||
Place the binding generation command into a Go source file before the package definition:
|
||||
|
||||
```
|
||||
//go:generate abigen --sol token.sol --pkg main --out token.go
|
||||
```
|
||||
|
||||
After which whenever the Solidity contract is modified, instead of needing to remember and
|
||||
run the above command, we can simply call `go generate` on the package (or even the entire
|
||||
source tree via `go generate ./...`), and it will correctly generate the new bindings for us.
|
||||
|
||||
## Blockchain simulator
|
||||
|
||||
Being able to deploy and access already deployed Ethereum contracts from within native Go
|
||||
code is an extremely powerful feature, but there is one facet with developing native code
|
||||
that not even the testnet lends itself well to: *automatic unit testing*. Using go-ethereum
|
||||
internal constructs it's possible to create test chains and verify them, but it is unfeasible
|
||||
to do high level contract testing with such low level mechanisms.
|
||||
|
||||
To sort out this last issue that would make it hard to run (and test) native DApps, we've also
|
||||
implemented a *simulated blockchain*, that can be set as a backend to native contracts the same
|
||||
way as a live RPC backend could be: `backends.NewSimulatedBackend(genesisAccounts)`.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Generate a new random account and a funded simulator
|
||||
key, _ := crypto.GenerateKey()
|
||||
auth := bind.NewKeyedTransactor(key)
|
||||
|
||||
sim := backends.NewSimulatedBackend(core.GenesisAccount{Address: auth.From, Balance: big.NewInt(10000000000)})
|
||||
|
||||
// Deploy a token contract on the simulated blockchain
|
||||
_, _, token, err := DeployMyToken(auth, sim, new(big.Int), "Simulated blockchain tokens", 0, "SBT")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to deploy new token contract: %v", err)
|
||||
}
|
||||
// Print the current (non existent) and pending name of the contract
|
||||
name, _ := token.Name(nil)
|
||||
fmt.Println("Pre-mining name:", name)
|
||||
|
||||
name, _ = token.Name(&bind.CallOpts{Pending: true})
|
||||
fmt.Println("Pre-mining pending name:", name)
|
||||
|
||||
// Commit all pending transactions in the simulator and print the names again
|
||||
sim.Commit()
|
||||
|
||||
name, _ = token.Name(nil)
|
||||
fmt.Println("Post-mining name:", name)
|
||||
|
||||
name, _ = token.Name(&bind.CallOpts{Pending: true})
|
||||
fmt.Println("Post-mining pending name:", name)
|
||||
}
|
||||
```
|
||||
|
||||
And the output (yay):
|
||||
|
||||
```
|
||||
Pre-mining name:
|
||||
Pre-mining pending name: Simulated blockchain tokens
|
||||
Post-mining name: Simulated blockchain tokens
|
||||
Post-mining pending name: Simulated blockchain tokens
|
||||
```
|
||||
|
||||
Note, that we don't have to wait for a local private chain miner, or testnet miner to
|
||||
integrate the currently pending transactions. When we decide to mine the next block,
|
||||
we simply `Commit()` the simulator.
|
@ -1,91 +0,0 @@
|
||||
---
|
||||
title: Mobile Clients
|
||||
---
|
||||
**This page has been obsoleted. An new guide is in the progress at [[Mobile: Introduction]]**
|
||||
|
||||
---
|
||||
|
||||
*This page is meant to be a guide on using go-ethereum from mobile platforms. Since neither the mobile libraries nor the light client protocol is finalized, the content here will be sparse, with emphasis being put on how to get your hands dirty. As the APIs stabilize this section will be expanded accordingly.*
|
||||
|
||||
### Changelog
|
||||
|
||||
* 30th September, 2016: Create initial page, upload Android light bundle.
|
||||
|
||||
### Background
|
||||
|
||||
Before reading further, please skim through the slides of a Devcon2 talk: [Import Geth: Ethereum from Go and beyond](https://ethereum.karalabe.com/talks/2016-devcon.html), which introduces the basic concepts behind using go-ethereum as a library, and also showcases a few code snippets on how you can do various client side tasks, both on classical computing nodes as well as Android devices. A recording of the talk will be linked when available.
|
||||
|
||||
*Please note, the Android and iOS library bundles linked in the presentation will not be updated (for obvious posterity reasons), so always grab latest bundles from this page (until everything is merged into the proper build infrastructure).*
|
||||
|
||||
### Mobile bundles
|
||||
|
||||
You can download the latest bundles at:
|
||||
|
||||
* [Android (30th September, 2016)](https://bintray.com/karalabe/ethereum/download_file?file_path=geth.aar) - `SHA1: 753e334bf61fa519bec83bcb487179e36d58fc3a`
|
||||
* iOS: *light client has not yet been bundled*
|
||||
|
||||
### Android quickstart
|
||||
|
||||
We assume you are using Android Studio for your development. Please download the latest Android `.aar` bundle from above and import it into your Android Studio project via `File -> New -> New Module`. This will result in a `geth` sub-project inside your work-space. To use the library in your project, please modify your apps `build.gradle` file, adding a dependency to the Geth library:
|
||||
|
||||
```gradle
|
||||
dependencies {
|
||||
// All your previous dependencies
|
||||
compile project(':geth')
|
||||
}
|
||||
```
|
||||
|
||||
To get you hands dirty, here's a code snippet that will
|
||||
|
||||
* Start up an in-process light node inside your Android application
|
||||
* Display some initial infos about your node
|
||||
* Subscribe to new blocks and display them live as they arrive
|
||||
|
||||
<img src="http://i.imgur.com/LyTCCqg.png" width="512px" />
|
||||
|
||||
```java
|
||||
import org.ethereum.geth.*;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
setTitle("Android In-Process Node");
|
||||
final TextView textbox = (TextView) findViewById(R.id.textbox);
|
||||
|
||||
Context ctx = new Context();
|
||||
|
||||
try {
|
||||
Node node = Geth.newNode(getFilesDir() + "/.ethereum", new NodeConfig());
|
||||
node.start();
|
||||
|
||||
NodeInfo info = node.getNodeInfo();
|
||||
textbox.append("My name: " + info.getName() + "\n");
|
||||
textbox.append("My address: " + info.getListenerAddress() + "\n");
|
||||
textbox.append("My protocols: " + info.getProtocols() + "\n\n");
|
||||
|
||||
EthereumClient ec = node.getEthereumClient();
|
||||
textbox.append("Latest block: " + ec.getBlockByNumber(ctx, -1).getNumber() + ", syncing...\n");
|
||||
|
||||
NewHeadHandler handler = new NewHeadHandler() {
|
||||
@Override public void onError(String error) { }
|
||||
@Override public void onNewHead(final Header header) {
|
||||
MainActivity.this.runOnUiThread(new Runnable() {
|
||||
public void run() { textbox.append("#" + header.getNumber() + ": " + header.getHash().getHex().substring(0, 10) + ".\n"); }
|
||||
});
|
||||
}
|
||||
};
|
||||
ec.subscribeNewHead(ctx, handler, 16);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Known quirks
|
||||
|
||||
* Many constructors (those that would throw exceptions) are of the form `Geth.newXXX()`, instead of simply the Java style `new XXX()` This is an upstream limitation of the [gomobile](https://github.com/golang/mobile) project, one which is currently being worked on to resolve.
|
||||
* There are zero documentations attached to the Java library methods. This too is a limitation of the [gomobile](https://github.com/golang/mobile) project. We will try to propose a fix upstream to make our docs from the Go codebase available in Java.
|
Reference in New Issue
Block a user