From 60146aea316aae62c7c78cde18c7fb826ff61e07 Mon Sep 17 00:00:00 2001 From: Adam Schmideg Date: Mon, 17 Dec 2018 12:43:02 +0100 Subject: [PATCH] copy markdown files from wiki --- docs/Accounts---key-storage-specification.md | 71 + docs/Achieving-Darkness.md | 49 + docs/Active-go-ethereum-projects.md | 32 + docs/Backup-&-restore.md | 61 + docs/Building-Ethereum.md | 19 + docs/Code-Review-Guidelines.md | 98 ++ docs/Command-Line-Options.md | 166 ++ docs/Connecting-to-the-network.md | 150 ++ docs/Contract-Tutorial.md | 932 ++++++++++++ ...ing-your-own-Ethereum-apps-using-Eth-go.md | 115 ++ docs/Cross-compiling-Ethereum.md | 164 ++ docs/Developer-Guide.md | 21 + docs/Developers'-Guide.md | 138 ++ docs/Diagnostic-Tool-wnode.md | 239 +++ docs/Disclaimer.md | 84 ++ docs/Ethereum-Specification.md | 28 + docs/Ethereum-on-Android.md | 63 + docs/FAQ.md | 46 + docs/Gas-Price-Oracle.md | 19 + docs/Geth.md | 108 ++ docs/Go-ethereum-management-API's.md | 1 + docs/How-to-Whisper.md | 97 ++ docs/IPFS-&-SWARM.md | 1 + docs/Installation-Instructions-for-ARM.md | 11 + docs/Installation-Instructions-for-Arch.md | 22 + docs/Installation-Instructions-for-FreeBSD.md | 57 + docs/Installation-Instructions-for-Mac.md | 55 + docs/Installation-Instructions-for-Ubuntu.md | 45 + docs/Installation-instructions-for-Windows.md | 63 + docs/Installing-Geth.md | 111 ++ docs/Installing-Go.md | 37 + docs/Issue-handling-workflow.md | 51 + docs/JavaScript-Console.md | 74 + docs/Management-APIs.md | 1329 +++++++++++++++++ docs/Managing-your-accounts.md | 347 +++++ docs/Metrics-and-Monitoring.md | 113 ++ docs/Mining.md | 291 ++++ docs/Peer-to-Peer.md | 158 ++ docs/Private-network.md | 105 ++ docs/Provisional-JS-API.md | 42 + docs/RPC-PUB-SUB.md | 142 ++ docs/Running-in-Docker.md | 35 + docs/Sending-ether.md | 31 + docs/Setting-up-Ethereum-(Native).md | 25 + .../Setting-up-monitoring-on-local-cluster.md | 54 + ...ing-up-private-network-or-local-cluster.md | 116 ++ docs/Swarm---TODO.md | 77 + docs/Swarm---distributed-preimage-archive.md | 68 + ...warm-Channels,-Namereg-resolution-draft.md | 163 ++ docs/Swarm-Contract.md | 37 + docs/URL-Scheme.md | 267 ++++ docs/Whisper-Overview.md | 169 +++ docs/Whisper-js-example.md | 41 + docs/Whisper-v5-RPC-API.md | 783 ++++++++++ docs/Whisper-v6-RPC-API.md | 783 ++++++++++ docs/Whisper.md | 19 + docs/[Japanese]-Contracts-and-Transactions.md | 394 +++++ docs/_Footer.md | 1 + docs/_Sidebar.md | 43 + docs/index.md | 17 + docs/swarm---POC-series.md | 57 + docs/swarm-dev-progress.md | 1 + docs/swarm-roadmap.md | 1 + index.html | 1 + 64 files changed, 8938 insertions(+) create mode 100644 docs/Accounts---key-storage-specification.md create mode 100644 docs/Achieving-Darkness.md create mode 100644 docs/Active-go-ethereum-projects.md create mode 100644 docs/Backup-&-restore.md create mode 100644 docs/Building-Ethereum.md create mode 100644 docs/Code-Review-Guidelines.md create mode 100644 docs/Command-Line-Options.md create mode 100644 docs/Connecting-to-the-network.md create mode 100644 docs/Contract-Tutorial.md create mode 100644 docs/Creating-your-own-Ethereum-apps-using-Eth-go.md create mode 100644 docs/Cross-compiling-Ethereum.md create mode 100644 docs/Developer-Guide.md create mode 100644 docs/Developers'-Guide.md create mode 100644 docs/Diagnostic-Tool-wnode.md create mode 100644 docs/Disclaimer.md create mode 100644 docs/Ethereum-Specification.md create mode 100644 docs/Ethereum-on-Android.md create mode 100644 docs/FAQ.md create mode 100644 docs/Gas-Price-Oracle.md create mode 100644 docs/Geth.md create mode 100644 docs/Go-ethereum-management-API's.md create mode 100644 docs/How-to-Whisper.md create mode 100644 docs/IPFS-&-SWARM.md create mode 100644 docs/Installation-Instructions-for-ARM.md create mode 100644 docs/Installation-Instructions-for-Arch.md create mode 100644 docs/Installation-Instructions-for-FreeBSD.md create mode 100644 docs/Installation-Instructions-for-Mac.md create mode 100644 docs/Installation-Instructions-for-Ubuntu.md create mode 100644 docs/Installation-instructions-for-Windows.md create mode 100644 docs/Installing-Geth.md create mode 100644 docs/Installing-Go.md create mode 100644 docs/Issue-handling-workflow.md create mode 100644 docs/JavaScript-Console.md create mode 100644 docs/Management-APIs.md create mode 100644 docs/Managing-your-accounts.md create mode 100644 docs/Metrics-and-Monitoring.md create mode 100644 docs/Mining.md create mode 100644 docs/Peer-to-Peer.md create mode 100644 docs/Private-network.md create mode 100644 docs/Provisional-JS-API.md create mode 100644 docs/RPC-PUB-SUB.md create mode 100644 docs/Running-in-Docker.md create mode 100644 docs/Sending-ether.md create mode 100644 docs/Setting-up-Ethereum-(Native).md create mode 100644 docs/Setting-up-monitoring-on-local-cluster.md create mode 100644 docs/Setting-up-private-network-or-local-cluster.md create mode 100644 docs/Swarm---TODO.md create mode 100644 docs/Swarm---distributed-preimage-archive.md create mode 100644 docs/Swarm-Channels,-Namereg-resolution-draft.md create mode 100644 docs/Swarm-Contract.md create mode 100644 docs/URL-Scheme.md create mode 100644 docs/Whisper-Overview.md create mode 100644 docs/Whisper-js-example.md create mode 100644 docs/Whisper-v5-RPC-API.md create mode 100644 docs/Whisper-v6-RPC-API.md create mode 100644 docs/Whisper.md create mode 100644 docs/[Japanese]-Contracts-and-Transactions.md create mode 100644 docs/_Footer.md create mode 100644 docs/_Sidebar.md create mode 100644 docs/index.md create mode 100644 docs/swarm---POC-series.md create mode 100644 docs/swarm-dev-progress.md create mode 100644 docs/swarm-roadmap.md diff --git a/docs/Accounts---key-storage-specification.md b/docs/Accounts---key-storage-specification.md new file mode 100644 index 0000000000..456637c787 --- /dev/null +++ b/docs/Accounts---key-storage-specification.md @@ -0,0 +1,71 @@ +**THIS PAGE IS PARTLY OUTDATED! TODO: REFACTOR OR DELETE** + +# Accounts / key storage specification + +This is an attempt to compile a single, written specification from the multiple sources which have so far been used for accounts / key storage specs: + +* Skype calls +* Skype chats +* Email conversations +* Github issues +* Github pull request comments +* Github commits +* Lively in-person discussions in the Amsterdam office. +* Several past instances of the Amsterdam office whiteboard contents. + +# Background + +Up until Ethereum PoC 8, the Go client has used a single, default key in plaintext on disk for use as wallet and for signing all txs. We want to extend this to have a more generic key storage supporting multiple keys. We also want an "accounts" abstraction over these keys where an account corresponds to a key, and a user can have multiple accounts and be able to send / receive to any of them. + +The goal of this is to support better wallet / account functionality both in Mist as well as in DAPPs. + +# Specification + +## Key Storage + +The key storage must support: + +1. Generation of new keys +2. Deletion of keys. +3. Multiple, uniquely identifiable keys. +4. Password protection of keys. +5. Persistence of keys (e.g. on disk) +6. Export & Import of keys. +7. Import of pre-sale keys (generated by https://github.com/ethereum/pyethsaletool) NOTE: this is a different import functionality than general import (6) +8. Proper use of secure cryptography for key generation, password protection, key persistence and export format of keys. +9. Mechanism for Backing the keys up – maybe automatically + +## Account Manager + +0. Account == address of an Ethereum account == address of EC public key of EC private key the user controls. + +The account manager must support: + +1. Account creation & deletion +2. Multiple, unique accounts. +3. Persistence of accounts (e.g. on disk) +4. An account is mapped to a single key. +5. The account is identifiable by some public, non-sensitive data. E.g. the Ethereum address of a EC keypair can be used as account identifier / address. + +## Mist + +The Mist UI must support: + +1. Creation of a new account. +2. Display a list of all available accounts (addresses) +3. Copy-paste of account addresses to easily use when receiving funds. +4. Choosing one of the available accounts when sending a tx. +5. Typing password when accessing one of the hot wallet keys +6. Showing the possible ways to temporarily input wallet keys when needed + +## RPC API + +The RPC API must support: + +1. The list of accounts is exposed through the eth_accounts API: https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_accounts +2. Using any of the available accounts as from/sender with the eth_transact API: https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_transact (NOTE: the current API definition on that wiki page does not include a from/sender field!) + + +## Wallet DAPP + +TODO: \ No newline at end of file diff --git a/docs/Achieving-Darkness.md b/docs/Achieving-Darkness.md new file mode 100644 index 0000000000..67cae3f937 --- /dev/null +++ b/docs/Achieving-Darkness.md @@ -0,0 +1,49 @@ +Whisper is designed to be a building block in the next generation of unstoppable ÐApps. It was designed to provide resilience and privacy at considerable expense. At its most secure mode of operation Whisper can theoretically deliver complete darkness. Whisper should also allow the users to configure the level of privacy (how much information it leaks concerning the ÐApp content and ultimately, user activities) as a trade-off for performance. In this article we will discuss the strategy of achieving complete darkness. + +### Adversary + +In the worst case, you are playing against a very powerful adversary, which has a capacity to run a lot of Whisper nodes. In addition to that, it might generate Whisper identities in order to target a specific node. For example, it might generate IDs that will be very close to the ID of the target node, which then fit into Kademlia topology in such a way that will allow a traffic analysis from this node. As a result, it will be possible to see which messages originate from the target node. + +### Recipient vs. Sender + +Even if most nodes of the network belong to adversary, it will be still impossible to identify the recipient of particular message by the means of simple traffic analysis. But the sender might be identified. In order to prevent that, the node might maintain a certain noise level. For example, if the node sends on average several messages per hour, it might still send random messages every minute. Those extra messages should resemble the meaningful messages, but should contain randomly generated bytes and be encrypted with random key, so that adversary will not be able to distinguish the meaningful messages from the noise. It is necessary to encrypt (not only generate) random data because encrypted messages might have some common traits, which distinguish them from noise. E.g. in case of asymmetric encryption some bytes are allowed to have only certain values. + +In some cases recipient might also be probabilistically identified if two nodes send each other messages with common traits, e.g. same Topic or same size. That's why it is important to use different Topics for sending and receiving the messages within the session. + +### Topics + +It is possible to send asymmetrically encrypted messages without any Topic. However, in case of huge traffic it might be not practical to try decrypting all the incoming messages, since decrypt operation is quite expensive. Some filtering might be necessary. Whisper allows to subscribe for messages with particular Topic or specify several possible Topics. It is also possible to subscribe for partial Topic(s), e.g. first one, two, or three bytes of the Topic. + +Topic collisions are part of the plausible deniability strategy. Some messages from different nodes (and encrypted with different keys) should have the same Topic (or partial Topic). Therefore it is recommended to set the Topics dynamically, so that collisions will regulary occur on your node. + +For example, if there are 6000 nodes in the network and each of them on average sends ten messages per minute, it would make sense to set only first byte of the Topic (leaving the other three bytes random). In this case each node will receive on average 1000 messages per second. The node will try to decrypt approximately four messages (those matching the Topic), and one of them will be successfully decrypted. The rest of the messages will be ignored and just forwarded to the other peers. + +### Message Size and Padding + +When sending the messages, another important metric which could potentially leak metainformation is the size. Therefore, depending on the circumstances, it might be useful to send messages only of certain size or always generate random size (not exceeding certain limit). The API allows easy setting of padding. The default implementation of Whisper also uses the padding to align the messages along the 256-byte boundaries. + +### Symmetric vs. Asymmetric + +In case of symmetric encryption, the nodes must have already exchanged the encryption key via some secure channel. So, they should use the same channel to exchange the Topics (or partial Topics), and maybe PoW requirement for individual messages. In case of asymmetric encryption, the public key is exchanged via open channels, and it might be impossible to exchange any other information before they engage in secure communication. In this case different strategies might be employed. + +For example, the first message might be sent without any Topic. This message may contain all the information necessary to start a symmetrically encrypted session, complete with (partial) Topics, PoW requirement and symmetric keys. Because it requires trying to decrypt all the incoming asymmetric messages, the PoW requirement for such messages might be set very high, which might be acceptable since such messages are only sent once per session. + +Alternatively, a partial Topic should be published along with the public key and PoW requirement. E.g., if we use two or three bytes for the partial Topic of symmetrically encrypted messages, we might only use one byte for the asymmetric encryption. + +### Example of Session + +Suppose two nodes want to engage in secure communication. One of them sends an asymmetrically encrypted message of certain (pre-defined) format, which contains two symmetric keys and corresponding partial Topics, all randomly generated. The sender of this message subscribes for the messages with the first Topic (encrypted with the first key), and always encrypts outgoing messages with the second key. The recipient subscribes for the messages with the second Topic (encrypted with the second key), and always encrypts outgoing messages with the first key. They also include the message number in each outgoing message, in order to ensure the correct order of the messages, and detect if some of them did not arrive. After the session is over, the keys are deleted and never used again. + +In case of several participants (e.g. a group chat) they just need one additional key and one additional subscription for any additional participant. + +### Plausible Deniability + +Suppose a user has lost control of his key. It might happen due to hacker attack on his computer, or becuase a hostile entity forces him to reveal the key. In case he signed any message with his private key, it might be used as evidence against him. So, the user might prefer to use his key only to establish the session, and then engage in symmetrically encrypted communication without signing the messages. His peer may be sure about his identity, since the symmetric key was signed with his private key. But these messages can not be used as evidence, since this message could have been sent by anyone in possession of the symmetric key, especially if this key was used in a group chat session. + +### Steganography + +However, in some extreme cases even plausible deniability might not be enough. In those cases users might utilize the padding mechanism for steganographic purposes. It is possible to set arbitrary data as padding. The Whisper API allows easy access to padding for both writing and reading. Since vast majority of the messages will contain some kind of padding (either default or customized), it will be impossible to distinguish between randomly generated and encrypted padding bytes. The users should only use such encryption which does not reveal any metainformation (preferably symmetric stream ciphers), and then add the resulting data as padding to a message with some irrelevant payload. + +### Private Networks + +It is very easy to set up a private Whisper network, since Whisper does not contain any genesis block or indeed any state at all. You just start a bootstrap node to which everybody should connect. It might be useful for organizations with restricted access. Private network may have several advantages. For example, it might be very difficult for any adversary to join the network, which will make the traffic analysis almost impossible. Also, PoW requirement might be dropped, thus allowing instant messaging with very little overhead. diff --git a/docs/Active-go-ethereum-projects.md b/docs/Active-go-ethereum-projects.md new file mode 100644 index 0000000000..4109a7f033 --- /dev/null +++ b/docs/Active-go-ethereum-projects.md @@ -0,0 +1,32 @@ +# 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 +- Blockscout for Puppeth diff --git a/docs/Backup-&-restore.md b/docs/Backup-&-restore.md new file mode 100644 index 0000000000..5a55560aed --- /dev/null +++ b/docs/Backup-&-restore.md @@ -0,0 +1,61 @@ +**DO NOT FORGET YOUR PASSWORD** and **BACKUP YOUR KEYSTORE** + +# Backup & restore + +## Data directory + +Everything `geth` persists gets written inside its data directory (except for the PoW Ethash DAG, see note below). +The default data directory locations are platform specific: + +* Mac: `~/Library/Ethereum` +* Linux: `~/.ethereum` +* Windows: `%APPDATA%\Ethereum` + +Accounts are stored in the `keystore` subdirectory. The contents of this directories should be transportable between nodes, platforms, implementations (C++, Go, Python). + +To configure the location of the data directory, the `--datadir` parameter can be specified. See [CLI Options](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options) for more details. + +_**Note:** The [Ethash DAG](https://github.com/ethereum/go-ethereum/wiki/Mining#ethash-dag) is stored at `~/.ethash` (Mac/Linux) or `%APPDATA%\Ethash` (Windows) so that it can be reused by all clients. You can store this in a different location by using a symbolic link._ + +## Upgrades + +Sometimes the internal database formats need updating (for example, when upgrade from before 0.9.20). This can be run with the following command (geth should not be otherwise running): + +``` +geth upgradedb +``` + +## Cleanup + +Geth's blockchain and state databases can be removed with: + +``` +geth removedb +``` + +This is useful for deleting an old chain and sync'ing to a new one. It only affects data directories that can be re-created on synchronisation and does not touch the keystore. + +## Blockchain import/export + +Export the blockchain in binary format with: +``` +geth export +``` + +Or if you want to back up portions of the chain over time, a first and last block can be specified. For example, to back up the first epoch: + +``` +geth export 0 29999 +``` + +Note that when backing up a partial chain, the file will be appended rather than truncated. + +Import binary-format blockchain exports with: +``` +geth import +``` + +_See https://github.com/ethereum/wiki/wiki/Blockchain-import-export for more info_ + + +And finally: **DO NOT FORGET YOUR PASSWORD** and **BACKUP YOUR KEYSTORE** \ No newline at end of file diff --git a/docs/Building-Ethereum.md b/docs/Building-Ethereum.md new file mode 100644 index 0000000000..39dc72a805 --- /dev/null +++ b/docs/Building-Ethereum.md @@ -0,0 +1,19 @@ +## Installation Instructions + +Follow the appropriate link below to find installation instructions for +your platform. + +* [Installation Instructions for Mac OS X](https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-Mac) +* [Installation Instructions for Windows](https://github.com/ethereum/go-ethereum/wiki/Installation-instructions-for-Windows) +* Installation Instructions for Linux/Unix + * [Ubuntu](https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-Ubuntu) + * [Arch](https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-Arch) + * [FreeBSD](https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-FreeBSD) +* [Setup for Raspberry Pi](https://github.com/ethereum/wiki/wiki/Raspberry-Pi-instructions) + * [ARM](https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-ARM) +* [Usage instructions for Docker](https://github.com/ethereum/go-ethereum/wiki/Running-in-Docker) + +## Quick Links + +* [Ubuntu PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum) +* [Download Page](https://geth.ethereum.org/downloads) \ No newline at end of file diff --git a/docs/Code-Review-Guidelines.md b/docs/Code-Review-Guidelines.md new file mode 100644 index 0000000000..d2d6682b03 --- /dev/null +++ b/docs/Code-Review-Guidelines.md @@ -0,0 +1,98 @@ +The only way to get code into go-ethereum is to send a pull request. Those pull requests +need to be reviewed by someone. This document is a guide that explains our expectations +around PRs for both authors and reviewers. + +## Terminology + +* The **author** of a pull request is the entity who wrote the diff and submitted it to + GitHub. +* The **team** consists of people with commit rights on the go-ethereum repository. +* The **reviewer** is the person assigned to review the diff. The reviewer must be a team + member. +* The **code owner** is the person responsible for the subsystem being modified by the PR. + +## The Process + +The first decision to make for any PR is whether it's worth including at all. This +decision lies primarily with the code owner, but may be negotiated with team members. + +To make the decision we must understand what the PR is about. If there isn't enough +description content or the diff is too large, request an explanation. Anyone can do this +part. + +We expect that reviewers check the style and functionality of the PR, providing comments +to the author using the GitHub review system. Reviewers should follow up with the PR until +it is in good shape, then **approve** the PR. Approved PRs can be merged by any code owner. + +When communicating with authors, be polite and respectful. + +### Code Style + +We expect `gofmt`ed code. For contributions of significant size, we expect authors to +understand and use the guidelines in [Effective Go][effgo]. Authors should avoid common +mistakes explained in the [Go Code Review Comments][revcomment] page. + +### Functional Checks + +For PRs that fix an issue, reviewers should try reproduce the issue and verify that the +pull request actually fixes it. Authors can help with this by including a unit test that +fails without (and passes with) the change. + +For PRs adding new features, reviewers should attempt to use the feature and comment on +how it feels to use it. Example: if a PR adds a new command line flag, use the program +with the flag and comment on whether the flag feels useful. + +We expect appropriate unit test coverage. Reviewers should verify that new code is covered +by unit tests. + +### CI + +Code submitted must pass all unit tests and static analysis ("lint") checks. We use Travis +CI to test code on Linux, macOS and AppVeyor to test code on Microsoft Windows. + +For failing CI builds, the issue may not be related to the PR itself. Such failures are +usually related to flakey tests. These failures can be ignored (authors don't need to fix +unrelated issues), but please file a GH issue so the test gets fixed eventually. + +### Commit Messages + +Commit messages on the master branch should follow the rule below. PR authors are not +required to use any particular style because the message can be modified at merge time. +Enforcing commit message style is the responsibility of the person merging the PR. + +The commit message style we use is similar to the style used by the Go project: + +The first line of the change description is conventionally a one-line summary of the +change, prefixed by the primary affected Go package. It should complete the sentence "This +change modifies go-ethereum to _____." The rest of the description elaborates and should +provide context for the change and explain what it does. + +Template: + +```text +package/path: change XYZ + +Longer explanation of the change in the commit. You can use +multiple sentences here. It's usually best to include content +from the PR description in the final commit message. + +issue notices, e.g. "Fixes #42353". +``` + +### Special Situations And How To Deal With Them + +As a reviewer, you may find yourself in one of the sitations below. Here's how to deal +with those: + +* The author doesn't follow up: ping them after a while (i.e. after a few days). If there + is no further response, close the PR or complete the work yourself. + +* Author insists on including refactoring changes alongside bug fix: We can tolerate small + refactorings alongside any change. If you feel lost in the diff, ask the author to + submit the refactoring as an independent PR, or at least as an independent commit in the + same PR. + +* Author keeps rejecting your feedback: reviewers have authority to reject any change for technical reasons. If you're unsure, ask the team for a second opinion. You may close the PR if no consensus can be reached. + +[effgo]: https://golang.org/doc/effective_go.html +[revcomment]: https://github.com/golang/go/wiki/CodeReviewComments diff --git a/docs/Command-Line-Options.md b/docs/Command-Line-Options.md new file mode 100644 index 0000000000..bdf8409adf --- /dev/null +++ b/docs/Command-Line-Options.md @@ -0,0 +1,166 @@ +``` +$ geth help +NAME: + geth - the go-ethereum command line interface + + Copyright 2013-2018 The go-ethereum Authors + +USAGE: + geth [options] command [command options] [arguments...] + +VERSION: + 1.8.11-stable + +COMMANDS: + account Manage accounts + attach Start an interactive JavaScript environment (connect to node) + bug opens a window to report a bug on the geth repo + console Start an interactive JavaScript environment + copydb Create a local chain from a target chaindata folder + dump Dump a specific block from storage + dumpconfig Show configuration values + export Export blockchain into file + export-preimages Export the preimage database into an RLP stream + import Import a blockchain file + import-preimages Import the preimage database from an RLP stream + init Bootstrap and initialize a new genesis block + js Execute the specified JavaScript files + license Display license information + makecache Generate ethash verification cache (for testing) + makedag Generate ethash mining DAG (for testing) + monitor Monitor and visualize node metrics + removedb Remove blockchain and state databases + version Print version numbers + wallet Manage Ethereum presale wallets + help, h Shows a list of commands or help for one command + +ETHEREUM OPTIONS: + --config value TOML configuration file + --datadir "/home/ligi/.ethereum" Data directory for the databases and keystore + --keystore Directory for the keystore (default = inside the datadir) + --nousb Disables monitoring for and managing USB hardware wallets + --networkid value Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby) (default: 1) + --testnet Ropsten network: pre-configured proof-of-work test network + --rinkeby Rinkeby network: pre-configured proof-of-authority test network + --syncmode "fast" Blockchain sync mode ("fast", "full", or "light") + --gcmode value Blockchain garbage collection mode ("full", "archive") (default: "full") + --ethstats value Reporting URL of a ethstats service (nodename:secret@host:port) + --identity value Custom node name + --lightserv value Maximum percentage of time allowed for serving LES requests (0-90) (default: 0) + --lightpeers value Maximum number of LES client peers (default: 100) + --lightkdf Reduce key-derivation RAM & CPU usage at some expense of KDF strength + +DEVELOPER CHAIN OPTIONS: + --dev Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled + --dev.period value Block period to use in developer mode (0 = mine only if transaction pending) (default: 0) + +ETHASH OPTIONS: + --ethash.cachedir Directory to store the ethash verification caches (default = inside the datadir) + --ethash.cachesinmem value Number of recent ethash caches to keep in memory (16MB each) (default: 2) + --ethash.cachesondisk value Number of recent ethash caches to keep on disk (16MB each) (default: 3) + --ethash.dagdir "/home/ligi/.ethash" Directory to store the ethash mining DAGs (default = inside home folder) + --ethash.dagsinmem value Number of recent ethash mining DAGs to keep in memory (1+GB each) (default: 1) + --ethash.dagsondisk value Number of recent ethash mining DAGs to keep on disk (1+GB each) (default: 2) + +TRANSACTION POOL OPTIONS: + --txpool.nolocals Disables price exemptions for locally submitted transactions + --txpool.journal value Disk journal for local transaction to survive node restarts (default: "transactions.rlp") + --txpool.rejournal value Time interval to regenerate the local transaction journal (default: 1h0m0s) + --txpool.pricelimit value Minimum gas price limit to enforce for acceptance into the pool (default: 1) + --txpool.pricebump value Price bump percentage to replace an already existing transaction (default: 10) + --txpool.accountslots value Minimum number of executable transaction slots guaranteed per account (default: 16) + --txpool.globalslots value Maximum number of executable transaction slots for all accounts (default: 4096) + --txpool.accountqueue value Maximum number of non-executable transaction slots permitted per account (default: 64) + --txpool.globalqueue value Maximum number of non-executable transaction slots for all accounts (default: 1024) + --txpool.lifetime value Maximum amount of time non-executable transaction are queued (default: 3h0m0s) + +PERFORMANCE TUNING OPTIONS: + --cache value Megabytes of memory allocated to internal caching (default: 1024) + --cache.database value Percentage of cache memory allowance to use for database io (default: 75) + --cache.gc value Percentage of cache memory allowance to use for trie pruning (default: 25) + --trie-cache-gens value Number of trie node generations to keep in memory (default: 120) + +ACCOUNT OPTIONS: + --unlock value Comma separated list of accounts to unlock + --password value Password file to use for non-interactive password input + +API AND CONSOLE OPTIONS: + --rpc Enable the HTTP-RPC server + --rpcaddr value HTTP-RPC server listening interface (default: "localhost") + --rpcport value HTTP-RPC server listening port (default: 8545) + --rpcapi value API's offered over the HTTP-RPC interface + --ws Enable the WS-RPC server + --wsaddr value WS-RPC server listening interface (default: "localhost") + --wsport value WS-RPC server listening port (default: 8546) + --wsapi value API's offered over the WS-RPC interface + --wsorigins value Origins from which to accept websockets requests + --ipcdisable Disable the IPC-RPC server + --ipcpath Filename for IPC socket/pipe within the datadir (explicit paths escape it) + --rpccorsdomain value Comma separated list of domains from which to accept cross origin requests (browser enforced) + --rpcvhosts value Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard. (default: "localhost") + --jspath loadScript JavaScript root path for loadScript (default: ".") + --exec value Execute JavaScript statement + --preload value Comma separated list of JavaScript files to preload into the console + +NETWORKING OPTIONS: + --bootnodes value Comma separated enode URLs for P2P discovery bootstrap (set v4+v5 instead for light servers) + --bootnodesv4 value Comma separated enode URLs for P2P v4 discovery bootstrap (light server, full nodes) + --bootnodesv5 value Comma separated enode URLs for P2P v5 discovery bootstrap (light server, light nodes) + --port value Network listening port (default: 30303) + --maxpeers value Maximum number of network peers (network disabled if set to 0) (default: 25) + --maxpendpeers value Maximum number of pending connection attempts (defaults used if set to 0) (default: 0) + --nat value NAT port mapping mechanism (any|none|upnp|pmp|extip:) (default: "any") + --nodiscover Disables the peer discovery mechanism (manual peer addition) + --v5disc Enables the experimental RLPx V5 (Topic Discovery) mechanism + --netrestrict value Restricts network communication to the given IP networks (CIDR masks) + --nodekey value P2P node key file + --nodekeyhex value P2P node key as hex (for testing) + +MINER OPTIONS: + --mine Enable mining + --minerthreads value Number of CPU threads to use for mining (default: 8) + --etherbase value Public address for block mining rewards (default = first account created) (default: "0") + --targetgaslimit value Target gas limit sets the artificial target gas floor for the blocks to mine (default: 4712388) + --gasprice "18000000000" Minimal gas price to accept for mining a transactions + --extradata value Block extra data set by the miner (default = client version) + +GAS PRICE ORACLE OPTIONS: + --gpoblocks value Number of recent blocks to check for gas prices (default: 20) + --gpopercentile value Suggested gas price is the given percentile of a set of recent transaction gas prices (default: 60) + +VIRTUAL MACHINE OPTIONS: + --vmdebug Record information useful for VM and contract debugging + +LOGGING AND DEBUGGING OPTIONS: + --metrics Enable metrics collection and reporting + --fakepow Disables proof-of-work verification + --nocompaction Disables db compaction after import + --verbosity value Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail (default: 3) + --vmodule value Per-module verbosity: comma-separated list of = (e.g. eth/*=5,p2p=4) + --backtrace value Request a stack trace at a specific logging statement (e.g. "block.go:271") + --debug Prepends log messages with call-site location (file and line number) + --pprof Enable the pprof HTTP server + --pprofaddr value pprof HTTP server listening interface (default: "127.0.0.1") + --pprofport value pprof HTTP server listening port (default: 6060) + --memprofilerate value Turn on memory profiling with the given rate (default: 524288) + --blockprofilerate value Turn on block profiling with the given rate (default: 0) + --cpuprofile value Write CPU profile to the given file + --trace value Write execution trace to the given file + +WHISPER (EXPERIMENTAL) OPTIONS: + --shh Enable Whisper + --shh.maxmessagesize value Max message size accepted (default: 1048576) + --shh.pow value Minimum POW accepted (default: 0.2) + +DEPRECATED OPTIONS: + --fast Enable fast syncing through state downloads (replaced by --syncmode) + --light Enable light client mode (replaced by --syncmode) + +MISC OPTIONS: + --help, -h show help + + +COPYRIGHT: + Copyright 2013-2018 The go-ethereum Authors + +``` \ No newline at end of file diff --git a/docs/Connecting-to-the-network.md b/docs/Connecting-to-the-network.md new file mode 100644 index 0000000000..696787228f --- /dev/null +++ b/docs/Connecting-to-the-network.md @@ -0,0 +1,150 @@ +## How Peers Are Found + +Geth continuously attempts to connect to other nodes on the network +until it has peers. If you have UPnP enabled on your router or run +ethereum on an Internet-facing server, it will also accept connections +from other nodes. + +Geth finds peers through something called the discovery protocol. In +the discovery protocol, nodes are gossipping with each other to find +out about other nodes on the network. In order to get going initially, +geth uses a set of bootstrap nodes whose endpoints are recorded in the +source code. + +To change the bootnodes on startup, use the `--bootnodes` option and +separate the nodes by commas. For example: + + geth --bootnodes enode://pubkey1@ip1:port1,enode://pubkey2@ip2:port2,enode://pubkey3@ip3:port3 + +## Common Problems With Connectivity + +Sometimes you just can't get connected. The most common reasons are +as follows: + +- Your local time might be incorrect. An accurate clock is required + to participate in the Ethereum network. Check your OS for how to resync + your clock (example sudo ntpdate -s time.nist.gov) because even 12 + seconds too fast can lead to 0 peers. +- Some firewall configurations can prevent UDP traffic from flowing. + You can use the static nodes feature or `admin.addPeer()` on the console + to configure connections by hand. + +To start geth without the discovery protocol, you can use the `--nodiscover` parameter. You only want this is you are running a test node or an experimental test network with fixed nodes. + +## Checking Connectivity + +To check how many peers the client is connected to in the interactive console, the `net` module has two attributes give you info about the number of peers and whether you are a listening node. + +```js +> net.listening +true +> net.peerCount +4 +``` + +To get more information about the connected peers, such as IP address and port number, supported protocols, use the `peers()` function of the `admin` object. `admin.peers()` returns the list of currently connected peers. + +``` +> admin.peers +[{ + ID: 'a4de274d3a159e10c2c9a68c326511236381b84c9ec52e72ad732eb0b2b1a2277938f78593cdbe734e6002bf23114d434a085d260514ab336d4acdc312db671b', + Name: 'Geth/v0.9.14/linux/go1.4.2', + Caps: 'eth/60', + RemoteAddress: '5.9.150.40:30301', + LocalAddress: '192.168.0.28:39219' +}, { + ID: 'a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c', + Name: 'Geth/v0.9.15/linux/go1.4.2', + Caps: 'eth/60', + RemoteAddress: '52.16.188.185:30303', + LocalAddress: '192.168.0.28:50995' +}, { + ID: 'f6ba1f1d9241d48138136ccf5baa6c2c8b008435a1c2bd009ca52fb8edbbc991eba36376beaee9d45f16d5dcbf2ed0bc23006c505d57ffcf70921bd94aa7a172', + Name: 'pyethapp_dd52/v0.9.13/linux2/py2.7.9', + Caps: 'eth/60, p2p/3', + RemoteAddress: '144.76.62.101:30303', + LocalAddress: '192.168.0.28:40454' +}, { + ID: 'f4642fa65af50cfdea8fa7414a5def7bb7991478b768e296f5e4a54e8b995de102e0ceae2e826f293c481b5325f89be6d207b003382e18a8ecba66fbaf6416c0', + Name: '++eth/Zeppelin/Rascal/v0.9.14/Release/Darwin/clang/int', + Caps: 'eth/60, shh/2', + RemoteAddress: '129.16.191.64:30303', + LocalAddress: '192.168.0.28:39705' +} ] + +``` + +To check the ports used by geth and also find your enode URI run: +``` +> admin.nodeInfo +{ + Name: 'Geth/v0.9.14/darwin/go1.4.2', + NodeUrl: 'enode://3414c01c19aa75a34f2dbd2f8d0898dc79d6b219ad77f8155abf1a287ce2ba60f14998a3a98c0cf14915eabfdacf914a92b27a01769de18fa2d049dbf4c17694@[::]:30303', + NodeID: '3414c01c19aa75a34f2dbd2f8d0898dc79d6b219ad77f8155abf1a287ce2ba60f14998a3a98c0cf14915eabfdacf914a92b27a01769de18fa2d049dbf4c17694', + IP: '::', + DiscPort: 30303, + TCPPort: 30303, + Td: '2044952618444', + ListenAddr: '[::]:30303' +} +``` + + +## Custom Networks + +Sometimes you might not need to connect to the live public network, +you can instead choose to create your own private testnet. This is +very useful if you don't need to test external contracts and want just +to test the technology, because you won't have to compete with other +miners and will easily generate a lot of test ether to play around +(replace 12345 with any non-negative number): + + geth -—networkid="12345" console + +It is also possible to run geth with a custom genesis block from a JSON file +by supplying the `--genesis` flag. The genesis JSON file should have the following +format: + +```js +{ + "alloc": { + "dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": { + "balance": "1606938044258990275541962092341162602522202993782792835301376" + }, + "e6716f9544a56c530d868e4bfbacb172315bdead": { + "balance": "1606938044258990275541962092341162602522202993782792835301376" + }, + ... + }, + "nonce": "0x000000000000002a", + "difficulty": "0x020000", + "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x", + "gasLimit": "0x2fefd8" +} +``` + +## Static nodes + +Geth also supports a feature called static nodes if you have certain +peers you always want to connect to. Static nodes are re-connected +on disconnects. You can configure permanent static nodes by putting something like +the following into `/geth/static-nodes.json`: + +```js +[ + "enode://f4642fa65af50cfdea8fa7414a5def7bb7991478b768e296f5e4a54e8b995de102e0ceae2e826f293c481b5325f89be6d207b003382e18a8ecba66fbaf6416c0@33.4.2.1:30303", + "enode://pubkey@ip:port" +] +``` + +You can also add static nodes at runtime via the js console using [`admin.addPeer()`](https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console#addpeer): + +```js +admin.addPeer("enode://f4642fa65af50cfdea8fa7414a5def7bb7991478b768e296f5e4a54e8b995de102e0ceae2e826f293c481b5325f89be6d207b003382e18a8ecba66fbaf6416c0@33.4.2.1:30303") +``` + +Caveat: Currently the console is lacking support for removing a peer, increasing peercount or adding a non-static peer but not to keep try reconnecting. diff --git a/docs/Contract-Tutorial.md b/docs/Contract-Tutorial.md new file mode 100644 index 0000000000..e07cefd441 --- /dev/null +++ b/docs/Contract-Tutorial.md @@ -0,0 +1,932 @@ +## Introduction + +Now that you mastered the basics on how to get started and how to send ether, it's time to get your hands dirty in what really makes ethereum stand out of the crowd: smart contracts. Smart contracts are pieces of code that live on the blockchain and execute commands exactly how they were told to. They can read other contracts, make decisions, send ether and execute other contracts. Contracts will exist and run as long as the whole network exists, and will only stop if they run out of gas or if they were programmed to self destruct. + +What can you do with contracts? You can do almost anything really, but for this guide let's do some simple things: You will get funds through a crowdfunding that, if successful, will supply a radically transparent and democratic organization that will only obey its own citizens, will never swerve away from its constitution and cannot be censored or shut down. And all that in less than 300 lines of code. + +So let's start now. + + +## Your first citizen: the greeter + +Now that you’ve mastered the basics of Ethereum, let’s move into your first serious contract. The Frontier is a big open territory and sometimes you might feel lonely, so our first order of business will be to create a little automatic companion to greet you whenever you feel lonely. We’ll call him the “Greeter”. + +The Greeter is an intelligent digital entity that lives on the blockchain and is able to have conversations with anyone who interacts with it, based on its input. It might not be a talker, but it’s a great listener. Here is its code: + +```js +contract mortal { + /* Define variable owner of the type address*/ + address owner; + + /* this function is executed at initialization and sets the owner of the contract */ + function mortal() { owner = msg.sender; } + + /* Function to recover the funds on the contract */ + function kill() { if (msg.sender == owner) suicide(owner); } +} + +contract greeter is mortal { + /* define variable greeting of the type string */ + string greeting; + + /* this runs when the contract is executed */ + function greeter(string _greeting) public { + greeting = _greeting; + } + + /* main function */ + function greet() constant returns (string) { + return greeting; + } +} +``` + +You'll notice that there are two different contracts in this code: _"mortal"_ and _"greeter"_. This is because Solidity (the high level contract language we are using) has *inheritance*, meaning that one contract can inherit characteristics of another. This is very useful to simplify coding as common traits of contracts don't need to be rewritten every time, and all contracts can be written in smaller, more readable chunks. So by just declaring that _greeter is mortal_ you inherited all characteristics from the "mortal" contract and kept the greeter code simple and easy to read. + +The inherited characteristic _"mortal"_ simply means that the greeter contract can be killed by its owner, to clean up the blockchain and recover funds locked into it when the contract is no longer needed. Contracts in ethereum are, by default, immortal and have no owner, meaning that once deployed the author has no special privileges anymore. Consider this before deploying. + +### Installing a compiler + +Before you are able to Deploy it though, you'll need two things: the compiled code, and the Application Binary Interface, which is a sort of reference template that defines how to interact with the contract. + +The first you can get by using a compiler. You should have a solidity compiler built in on your geth console. To test it, use this command: + + eth.getCompilers() + +If you have it installed, it should output something like this: + + ['Solidity' ] + +If instead the command returns an error, then you need to install it. + +#### Using an online compiler + +If you don't have solC installed, we have a [online solidity compiler](https://chriseth.github.io/cpp-ethereum/) available. But be aware that **if the compiler is compromised, your contract is not safe**. For this reason, if you want to use the online compiler we encourage you to [host your own](https://github.com/chriseth/browser-solidity). + +#### Install SolC on Ubuntu + +Press control+c to exit the console (or type _exit_) and go back to the command line. Open the terminal and execute these commands: + + sudo add-apt-repository ppa:ethereum/ethereum + sudo apt-get update + sudo apt-get install solc + which solc + +Take note of the path given by the last line, you'll need it soon. + +#### Install SolC on Mac OSX + +You need [brew](http://brew.sh) in order to install on your mac + + brew tap ethereum/ethereum + brew install solidity + which solc + +Take note of the path given by the last line, you'll need it soon. + +#### Install SolC on Windows + +You need [chocolatey](http://chocolatey.org) in order to install solc. + + cinst -pre solC-stable + +Windows is more complicated than that, you'll need to wait a bit more. + +If you have the SolC Solidity Compiler installed, you need now reformat by removing spaces so it fits into a string variable [(there are some online tools that will do this)](http://www.textfixer.com/tools/remove-line-breaks.php): + +#### Compile from source + + git clone https://github.com/ethereum/cpp-ethereum.git + mkdir cpp-ethereum/build + cd cpp-ethereum/build + cmake -DJSONRPC=OFF -DMINER=OFF -DETHKEY=OFF -DSERPENT=OFF -DGUI=OFF -DTESTS=OFF -DJSCONSOLE=OFF .. + make -j4 + make install + which solc + +#### Linking your compiler in Geth + +Now [go back to the console](../geth) and type this command to install solC, replacing _path/to/solc_ to the path that you got on the last command you did: + + admin.setSolc("path/to/solc") + +Now type again: + + eth.getCompilers() + +If you now have solC installed, then congratulations, you can keep reading. If you don't, then go to our [forums](http://forum.ethereum.org) or [subreddit](http://www.reddit.com/r/ethereum) and berate us on failing to make the process easier. + + +### Compiling your contract + + +If you have the compiler installed, you need now reformat your contract by removing line-breaks so it fits into a string variable [(there are some online tools that will do this)](http://www.textfixer.com/tools/remove-line-breaks.php): + + var greeterSource = 'contract mortal { address owner; function mortal() { owner = msg.sender; } function kill() { if (msg.sender == owner) suicide(owner); } } contract greeter is mortal { string greeting; function greeter(string _greeting) public { greeting = _greeting; } function greet() constant returns (string) { return greeting; } }' + + var greeterCompiled = web3.eth.compile.solidity(greeterSource) + +You have now compiled your code. Now you need to get it ready for deployment, this includes setting some variables up, like what is your greeting. Edit the first line below to something more interesting than 'Hello World!" and execute these commands: + + var _greeting = "Hello World!" + var greeterContract = web3.eth.contract(greeterCompiled.greeter.info.abiDefinition); + + var greeter = greeterContract.new(_greeting,{from:web3.eth.accounts[0], data: greeterCompiled.greeter.code, gas: 1000000}, function(e, contract){ + if(!e) { + + if(!contract.address) { + console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); + + } else { + console.log("Contract mined! Address: " + contract.address); + console.log(contract); + } + + } + }) + +#### Using the online compiler + +If you don't have solC installed, you can simply use the online compiler. Copy the source code above to the [online solidity compiler](https://chriseth.github.io/cpp-ethereum/) and then your compiled code should appear on the left pane. Copy the code on the box labeled **Geth deploy** to a text file. Now change the first line to your greeting: + + var _greeting = "Hello World!" + +Now you can paste the resulting text on your geth window. Wait up to thirty seconds and you'll see a message like this: + + Contract mined! address: 0xdaa24d02bad7e9d6a80106db164bad9399a0423e + +You will probably be asked for the password you picked in the beginning, because you need to pay for the gas costs to deploying your contract. This contract is estimated to need 172 thousand gas to deploy (according to the [online solidity compiler](https://chriseth.github.io/cpp-ethereum/)), at the time of writing, gas on the test net is priced at 1 to 10 microethers per unit of gas (nicknamed "szabo" = 1 followed by 12 zeroes in wei). To know the latest price in ether all you can see the [latest gas prices at the network stats page](https://stats.ethdev.com) and multiply both terms. + +**Notice that the cost is not paid to the [ethereum developers](../foundation), instead it goes to the _Miners_, people who are running computers who keep the network running. Gas price is set by the market of the current supply and demand of computation. If the gas prices are too high, you can be a miner and lower your asking price.** + + +After less than a minute, you should have a log with the contract address, this means you've sucessfully deployed your contract. You can verify the deployed code (compiled) by using this command: + + eth.getCode(greeter.address) + +If it returns anything other than "0x" then congratulations! Your little Greeter is live! If the contract is created again (by performing another eth.sendTransaction), it will be published to a new address. + + +### Run the Greeter + +In order to call your bot, just type the following command in your terminal: + + greeter.greet(); + +Since this call changes nothing on the blockchain, it returns instantly and without any gas cost. You should see it return your greeting: + + 'Hello World!' + + +### Getting other people to interact with your code + +In order to other people to run your contract they need two things: the address where the contract is located and the ABI (Application Binary Interface) which is a sort of user manual, describing the name of its functions and how to call them. In order to get each of them run these commands: + + greeterCompiled.greeter.info.abiDefinition; + greeter.address; + +Then you can instantiate a javascript object which can be used to call the contract on any machine connected to the network. Replace 'ABI' and 'address' to create a contract object in javascript: + + var greeter = eth.contract(ABI).at(Address); + +This particular example can be instantiated by anyone by simply calling: + + var greeter2 = eth.contract([{constant:false,inputs:[],name:'kill',outputs:[],type:'function'},{constant:true,inputs:[],name:'greet',outputs:[{name:'',type:'string'}],type:'function'},{inputs:[{name:'_greeting',type:'string'}],type:'constructor'}]).at('greeterAddress'); + +Replace _greeterAddress_ with your contract's address. + + +**Tip: if the solidity compiler isn't properly installed in your machine, you can get the ABI from the online compiler. To do so, use the code below carefully replacing _greeterCompiled.greeter.info.abiDefinition_ with the abi from your compiler.** + + +### Cleaning up after yourself: + +You must be very excited to have your first contract live, but this excitement wears off sometimes, when the owners go on to write further contracts, leading to the unpleasant sight of abandoned contracts on the blockchain. In the future, blockchain rent might be implemented in order to increase the scalability of the blockchain but for now, be a good citizen and humanely put down your abandoned bots. + +Unlike last time we will not be making a call as we wish to change something on the blockchain. This requires a transaction be sent to the network and a fee to be paid for the changes made. The suicide is subsidized by the network so it will cost much less than a usual transaction. + + greeter.kill.sendTransaction({from:eth.accounts[0]}) + +You can verify that the deed is done simply seeing if this returns 0: + + eth.getCode(greeter.contractAddress) + +Notice that every contract has to implement its own kill clause. In this particular case only the account that created the contract can kill it. + +If you don't add any kill clause it could potentially live forever (or at least until the frontier contracts are all wiped) independently of you and any earthly borders, so before you put it live check what your local laws say about it, including any possible limitation on technology export, restrictions on speech and maybe any legislation on the civil rights of sentient digital beings. Treat your bots humanely. + + + + + +## The Coin + +What is a coin? Coins are much more interesting and useful than they seem, they are in essence just a tradeable token, but can become much more, depending on how you use them. Its value depends on what you do with it: a token can be used to control access (**an entrance ticket**), can be used for voting rights in an organization (**a share**), can be placeholders for an asset held by a third party (**a certificate of ownership**) or even be simply used as an exchange of value within a community (**a currency**). + +You could do all those things by creating a centralized server, but using an Ethereum token contract comes with some free functionalities: for one, it's a decentralized service and tokens can be still exchanged even if the original service goes down for any reason. The code can guarantee that no tokens will ever be created other than the ones set in the original code. Finally, by having each user hold their own token, this eliminates the scenarios where one single server break-in can result in the loss of funds from thousands of clients. + +You could create your own token on a different blockchain, but creating on ethereum is easier — so you can focus your energy on the innovation that will make your coin stand out - and it's more secure, as your security is provided by all the miners who are supporting the ethereum network. Finally, by creating your token in Ethereum, your coin will be compatible with any other contract running on ethereum. + +### The Code + +This is the code for the contract we're building: + + contract token { + mapping (address => uint) public coinBalanceOf; + event CoinTransfer(address sender, address receiver, uint amount); + + /* Initializes contract with initial supply tokens to the creator of the contract */ + function token(uint supply) { + coinBalanceOf[msg.sender] = supply; + } + + /* Very simple trade function */ + function sendCoin(address receiver, uint amount) returns(bool sufficient) { + if (coinBalanceOf[msg.sender] < amount) return false; + coinBalanceOf[msg.sender] -= amount; + coinBalanceOf[receiver] += amount; + CoinTransfer(msg.sender, receiver, amount); + return true; + } + } + +If you have ever programmed, you won't find it hard to understand what it does: it is a contract that generates 10 thousand tokens to the creator of the contract, and then allows anyone with enough balance to send it to others. These tokens are the minimum tradeable unit and cannot be subdivided, but for the final users could be presented as a 100 units subdividable by 100 subunits, so owning a single token would represent having 0.01% of the total. If your application needs more fine grained atomic divisibility, then just increase the initial issuance amount. + +In this example we declared the variable "coinBalanceOf" to be public, this will automatically create a function that checks any account's balance. + +### Compile and Deploy + +**So let's run it!** + + var tokenSource = ' contract token { mapping (address => uint) public coinBalanceOf; event CoinTransfer(address sender, address receiver, uint amount); /* Initializes contract with initial supply tokens to the creator of the contract */ function token(uint supply) { coinBalanceOf[msg.sender] = supply; } /* Very simple trade function */ function sendCoin(address receiver, uint amount) returns(bool sufficient) { if (coinBalanceOf[msg.sender] < amount) return false; coinBalanceOf[msg.sender] -= amount; coinBalanceOf[receiver] += amount; CoinTransfer(msg.sender, receiver, amount); return true; } }' + + var tokenCompiled = eth.compile.solidity(tokenSource) + +Now let’s set up the contract, just like we did in the previous section. Change the "initial Supply" to the amount of non divisible tokens you want to create. If you want to have divisible units, you should do that on the user frontend but keep them represented in the minimun unit of account. + + var supply = 10000; + var tokenContract = web3.eth.contract(tokenCompiled.token.info.abiDefinition); + var token = tokenContract.new( + supply, + { + from:web3.eth.accounts[0], + data:tokenCompiled.token.code, + gas: 1000000 + }, function(e, contract){ + if(!e) { + + if(!contract.address) { + console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); + + } else { + console.log("Contract mined! Address: " + contract.address); + console.log(contract); + } + + } + }) + +#### Online Compiler + +**If you don't have solC installed, you can simply use the online compiler.** Copy the contract code to the [online solidity compiler](https://chriseth.github.io/cpp-ethereum/), if there are no errors on the contract you should see a text box labeled **Geth Deploy**. Copy the content to a text file so you can change the first line to set the initial supply, like this: + + var supply = 10000; + +Now you can paste the resulting text on your geth window. Wait up to thirty seconds and you'll see a message like this: + + Contract mined! address: 0xdaa24d02bad7e9d6a80106db164bad9399a0423e + + +### Check balance watching coin transfers + +If everything worked correctly, you should be able to check your own balance with: + + token.coinBalanceOf(eth.accounts[0]) + " tokens" + +It should have all the 10 000 tokens that were created once the contract was published. Since there is not any other defined way for new coins to be issued, these are all that will ever exist. + +You can set up a **Watcher** to react whenever anyone sends a coin using your contract. Here's how you do it: + + var event = token.CoinTransfer({}, '', function(error, result){ + if (!error) + console.log("Coin transfer: " + result.args.amount + " tokens were sent. Balances now are as following: \n Sender:\t" + result.args.sender + " \t" + token.coinBalanceOf.call(result.args.sender) + " tokens \n Receiver:\t" + result.args.receiver + " \t" + token.coinBalanceOf.call(result.args.receiver) + " tokens" ) + }); + +### Sending coins + +Now of course those tokens aren't very useful if you hoard them all, so in order to send them to someone else, use this command: + + token.sendCoin.sendTransaction(eth.accounts[1], 1000, {from: eth.accounts[0]}) + +If a friend has registered a name on the registrar you can send it without knowing their address, doing this: + + token.sendCoin.sendTransaction(registrar.addr("Alice"), 2000, {from: eth.accounts[0]}) + + +Note that our first function **coinBalanceOf** was simply called directly on the contract instance and returned a value. This was possible since this was a simple read operation that incurs no state change and which executes locally and synchronously. Our second function **sendCoin** needs a **.sendTransaction()** call. Since this function is meant to change the state (write operation), it is sent as a transaction to the network to be picked up by miners and included in the canonical blockchain. As a result the consensus state of all participant nodes will adequately reflect the state changes resulting from executing the transaction. Sender address needs to be sent as part of the transaction to fund the fuel needed to run the transaction. Now, wait a minute and check both accounts balances: + + token.coinBalanceOf.call(eth.accounts[0])/100 + "% of all tokens" + token.coinBalanceOf.call(eth.accounts[1])/100 + "% of all tokens" + token.coinBalanceOf.call(registrar.addr("Alice"))/100 + "% of all tokens" + + +### Improvement suggestions + +Right now this cryptocurrency is quite limited as there will only ever be 10,000 coins and all are controlled by the coin creator, but you can change that. You could for example reward ethereum miners, by creating a transaction that will reward who found the current block: + + mapping (uint => address) miningReward; + function claimMiningReward() { + if (miningReward[block.number] == 0) { + coinBalanceOf[block.coinbase] += 1; + miningReward[block.number] = block.coinbase; + } + } + +You could modify this to anything else: maybe reward someone who finds a solution for a new puzzle, wins a game of chess, install a solar panel—as long as that can be somehow translated to a contract. Or maybe you want to create a central bank for your personal country, so you can keep track of hours worked, favours owed or control of property. In that case you might want to add a function to allow the bank to remotely freeze funds and destroy tokens if needed. + + +### Register a name for your coin + +The commands mentioned only work because you have token javascript object instantiated on your local machine. If you send tokens to someone they won't be able to move them forward because they don't have the same object and wont know where to look for your contract or call its functions. In fact if you restart your console these objects will be deleted and the contracts you've been working on will be lost forever. So how do you instantiate the contract on a clean machine? + +There are two ways. Let's start with the quick and dirty, providing your friends with a reference to your contract’s ABI: + + token = eth.contract([{constant:false,inputs:[{name:'receiver',type:'address'},{name:'amount',type:'uint256'}],name:'sendCoin',outputs:[{name:'sufficient',type:'bool'}],type:'function'},{constant:true,inputs:[{name:'',type:'address'}],name:'coinBalanceOf',outputs:[{name:'',type:'uint256'}],type:'function'},{inputs:[{name:'supply',type:'uint256'}],type:'constructor'},{anonymous:false,inputs:[{indexed:false,name:'sender',type:'address'},{indexed:false,name:'receiver',type:'address'},{indexed:false,name:'amount',type:'uint256'}],name:'CoinTransfer',type:'event'}]).at('0x4a4ce7844735c4b6fc66392b200ab6fe007cfca8') + +Just replace the address at the end for your own token address, then anyone that uses this snippet will immediately be able to use your contract. Of course this will work only for this specific contract so let's analyze step by step and see how to improve this code so you'll be able to use it anywhere. + +All accounts are referenced in the network by their public address. But addresses are long, difficult to write down, hard to memorize and immutable. The last one is specially important if you want to be able to generate fresh accounts in your name, or upgrade the code of your contract. In order to solve this, there is a default name registrar contract which is used to associate the long addresses with short, human-friendly names. + +Names have to use only alphanumeric characters and, cannot contain blank spaces. In future releases the name registrar will likely implement a bidding process to prevent name squatting but for now, it works on a first come first served basis: as long as no one else registered the name, you can claim it. + + +First, if you register a name, then you won't need the hardcoded address in the end. Select a nice coin name and try to reserve it for yourself. First, select your name: + + var tokenName = "MyFirstCoin" + +Then, check the availability of your name: + + registrar.addr(tokenName) + +If that function returns "0x00..", you can claim it to yourself: + + registrar.reserve.sendTransaction(tokenName, {from: eth.accounts[0]}); + + +Wait for the previous transaction to be picked up. Wait up to thirty seconds and then try: + + registrar.owner(myName) + +If it returns your address, it means you own that name and are able to set your chosen name to any address you want: + + registrar.setAddress.sendTransaction(tokenName, token.address, true,{from: eth.accounts[0]}); + +_You can replace **token.address** for **eth.accounts[0]** if you want to use it as a personal nickname._ + +Wait a little bit for that transaction to be picked up too and test it: + + registrar.addr("MyFirstCoin") + +You can send a transaction to anyone or any contract by name instead of account simply by typing + + eth.sendTransaction({from: eth.accounts[0], to: registrar.addr("MyFirstCoin"), value: web3.toWei(1, "ether")}) + +**Tip: don't mix registrar.addr for registrar.owner. The first is to which address that name is pointed at: anyone can point a name to anywhere else, just like anyone can forward a link to google.com, but only the owner of the name can change and update the link. You can set both to be the same address.** + +This should now return your token address, meaning that now the previous code to instantiate could use a name instead of an address. + + token = eth.contract([{constant:false,inputs:[{name:'receiver',type:'address'},{name:'amount',type:'uint256'}],name:'sendCoin',outputs:[{name:'sufficient',type:'bool'}],type:'function'},{constant:true,inputs:[{name:'',type:'address'}],name:'coinBalanceOf',outputs:[{name:'',type:'uint256'}],type:'function'},{inputs:[{name:'supply',type:'uint256'}],type:'constructor'},{anonymous:false,inputs:[{indexed:false,name:'sender',type:'address'},{indexed:false,name:'receiver',type:'address'},{indexed:false,name:'amount',type:'uint256'}],name:'CoinTransfer',type:'event'}]).at(registrar.addr("MyFirstCoin")) + +This also means that the owner of the coin can update the coin by pointing the registrar to the new contract. This would, of course, require the coin holders trust the owner set at registrar.owner("MyFirstCoin") + +### Learn More + +* [Meta coin standard](https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs) is a proposed standardization of function names for coin and token contracts, to allow them to be automatically added to other ethereum contract that utilizes trading, like exchanges or escrow. + +* [Formal proofing](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format#documentation-output) is a way where the contract developer will be able to assert some invariant qualities of the contract, like the total cap of the coin. *Not yet implemented*. + + + +# Crowdfund your idea + +Sometimes a good idea takes a lot of funds and collective effort. You could ask for donations, but donors prefer to give to projects they are more certain that will get traction and proper funding. This is an example where a crowdfunding would be ideal: you set up a goal and a deadline for reaching it. If you miss your goal, the donations are returned, therefore reducing the risk for donors. Since the code is open and auditable, there is no need for a centralized trusted platform and therefore the only fees everyone will pay are just the gas fees. + +In a crowdfunding prizes are usually given. This would require you to get everyone's contact information and keep track of who owns what. But since you just created your own token, why not use that to keep track of the prizes? This allows donors to immediately own something after they donated. They can store it safely, but they can also sell or trade it if they realize they don't want the prize anymore. If your idea is something physical, all you have to do after the project is completed is to give the product to everyone who sends you back a token. If the project is digital the token itself can immediately be used for users to participate or get entry on your project. + +### The code + +The way this particular crowdsale contract works is that you set an exchange rate for your token and then the donors will immediately get a proportional amount of tokens in exchange of their ether. You will also choose a funding goal and a deadline: once that deadline is over you can ping the contract and if the goal was reached it will send the ether raised to you, otherwise it goes back to the donors. Donors keep their tokens even if the project doesn't reach its goal, as a proof that they helped. + + + contract token { mapping (address => uint) public coinBalanceOf; function token() {} function sendCoin(address receiver, uint amount) returns(bool sufficient) { } } + + contract Crowdsale { + + address public beneficiary; + uint public fundingGoal; uint public amountRaised; uint public deadline; uint public price; + token public tokenReward; + Funder[] public funders; + event FundTransfer(address backer, uint amount, bool isContribution); + + /* data structure to hold information about campaign contributors */ + struct Funder { + address addr; + uint amount; + } + + /* at initialization, setup the owner */ + function Crowdsale(address _beneficiary, uint _fundingGoal, uint _duration, uint _price, token _reward) { + beneficiary = _beneficiary; + fundingGoal = _fundingGoal; + deadline = now + _duration * 1 minutes; + price = _price; + tokenReward = token(_reward); + } + + /* The function without name is the default function that is called whenever anyone sends funds to a contract */ + function () { + uint amount = msg.value; + funders[funders.length++] = Funder({addr: msg.sender, amount: amount}); + amountRaised += amount; + tokenReward.sendCoin(msg.sender, amount / price); + FundTransfer(msg.sender, amount, true); + } + + modifier afterDeadline() { if (now >= deadline) _ } + + /* checks if the goal or time limit has been reached and ends the campaign */ + function checkGoalReached() afterDeadline { + if (amountRaised >= fundingGoal){ + beneficiary.send(amountRaised); + FundTransfer(beneficiary, amountRaised, false); + } else { + FundTransfer(0, 11, false); + for (uint i = 0; i < funders.length; ++i) { + funders[i].addr.send(funders[i].amount); + FundTransfer(funders[i].addr, funders[i].amount, false); + } + } + suicide(beneficiary); + } + } + +### Set the parameters + +Before we go further, let's start by setting the parameters of the crowdsale: + + var _beneficiary = eth.accounts[1]; // create an account for this + var _fundingGoal = web3.toWei(100, "ether"); // raises 100 ether + var _duration = 30; // number of minutes the campaign will last + var _price = web3.toWei(0.02, "ether"); // the price of the tokens, in ether + var _reward = token.address; // the token contract address. + +On Beneficiary put the new address that will receive the raised funds. The funding goal is the amount of ether to be raised. Deadline is measured in blocktimes which average 12 seconds, so the default is about 4 weeks. The price is tricky: but just change the number 2 for the amount of tokens the contributors will receive for each ether donated. Finally reward should be the address of the token contract you created in the last section. + +In this example you are selling on the crowdsale half of all the tokens that ever existed, in exchange for 100 ether. Decide those parameters very carefully as they will play a very important role in the next part of our guide. + +### Deploy + +You know the drill: if you are using the solC compiler,[remove line breaks](http://www.textfixer.com/tools/remove-line-breaks.php) and copy the following commands on the terminal: + + + var crowdsaleCompiled = eth.compile.solidity(' contract token { mapping (address => uint) public coinBalanceOf; function token() {} function sendCoin(address receiver, uint amount) returns(bool sufficient) { } } contract Crowdsale { address public beneficiary; uint public fundingGoal; uint public amountRaised; uint public deadline; uint public price; token public tokenReward; Funder[] public funders; event FundTransfer(address backer, uint amount, bool isContribution); /* data structure to hold information about campaign contributors */ struct Funder { address addr; uint amount; } /* at initialization, setup the owner */ function Crowdsale(address _beneficiary, uint _fundingGoal, uint _duration, uint _price, token _reward) { beneficiary = _beneficiary; fundingGoal = _fundingGoal; deadline = now + _duration * 1 minutes; price = _price; tokenReward = token(_reward); } /* The function without name is the default function that is called whenever anyone sends funds to a contract */ function () { Funder f = funders[++funders.length]; f.addr = msg.sender; f.amount = msg.value; amountRaised += f.amount; tokenReward.sendCoin(msg.sender, f.amount/price); FundTransfer(f.addr, f.amount, true); } modifier afterDeadline() { if (now >= deadline) _ } /* checks if the goal or time limit has been reached and ends the campaign */ function checkGoalReached() afterDeadline { if (amountRaised >= fundingGoal){ beneficiary.send(amountRaised); FundTransfer(beneficiary, amountRaised, false); } else { FundTransfer(0, 11, false); for (uint i = 0; i < funders.length; ++i) { funders[i].addr.send(funders[i].amount); FundTransfer(funders[i].addr, funders[i].amount, false); } } suicide(beneficiary); } }'); + + var crowdsaleContract = web3.eth.contract(crowdsaleCompiled.Crowdsale.info.abiDefinition); + var crowdsale = crowdsaleContract.new( + _beneficiary, + _fundingGoal, + _duration, + _price, + _reward, + { + from:web3.eth.accounts[0], + data:crowdsaleCompiled.Crowdsale.code, + gas: 1000000 + }, function(e, contract){ + if(!e) { + + if(!contract.address) { + console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); + + } else { + console.log("Contract mined! Address: " + contract.address); + console.log(contract); + } + + } }) + +**If you are using the _online compiler_ Copy the contract code to the [online solidity compiler](https://chriseth.github.io/cpp-ethereum/), and then grab the content of the box labeled **Geth Deploy**. Since you have already set the parameters, you don't need to change anything to that text, simply paste the resulting text on your geth window.** + +Wait up to thirty seconds and you'll see a message like this: + + Contract mined! address: 0xdaa24d02bad7e9d6a80106db164bad9399a0423e + +If you received that alert then your code should be online. You can always double check by doing this: + + eth.getCode(crowdsale.address) + +Now fund your newly created contract with the necessary tokens so it can automatically distribute rewards to the contributors! + + token.sendCoin.sendTransaction(crowdsale.address, 5000,{from: eth.accounts[0]}) + +After the transaction is picked, you can check the amount of tokens the crowdsale address has, and all other variables this way: + + "Current crowdsale must raise " + web3.fromWei(crowdsale.fundingGoal.call(), "ether") + " ether in order to send it to " + crowdsale.beneficiary.call() + "." + + + +### Put some watchers on + +You want to be alerted whenever your crowdsale receives new funds, so paste this code: + + var event = crowdsale.FundTransfer({}, '', function(error, result){ + if (!error) + + if (result.args.isContribution) { + console.log("\n New backer! Received " + web3.fromWei(result.args.amount, "ether") + " ether from " + result.args.backer ) + + console.log( "\n The current funding at " +( 100 * crowdsale.amountRaised.call() / crowdsale.fundingGoal.call()) + "% of its goals. Funders have contributed a total of " + web3.fromWei(crowdsale.amountRaised.call(), "ether") + " ether."); + + var timeleft = Math.floor(Date.now() / 1000)-crowdsale.deadline(); + if (timeleft>3600) { console.log("Deadline has passed, " + Math.floor(timeleft/3600) + " hours ago") + } else if (timeleft>0) { console.log("Deadline has passed, " + Math.floor(timeleft/60) + " minutes ago") + } else if (timeleft>-3600) { console.log(Math.floor(-1*timeleft/60) + " minutes until deadline") + } else { console.log(Math.floor(-1*timeleft/3600) + " hours until deadline") + } + + } else { + console.log("Funds transferred from crowdsale account: " + web3.fromWei(result.args.amount, "ether") + " ether to " + result.args.backer ) + } + + }); + + + + +### Register the contract + +You are now set. Anyone can now contribute by simply sending ether to the crowdsale address, but to make it even simpler, let's register a name for your sale. First, pick a name for your crowdsale: + + var name = "mycrowdsale" + +Check if that's available and register: + + registrar.addr(name) + registrar.reserve.sendTransaction(name, {from: eth.accounts[0]}); + +Wait for the previous transaction to be picked up and then: + + registrar.setAddress.sendTransaction(name, crowdsale.address, true,{from: eth.accounts[0]}); + + +### Contribute to the crowdsale + +Contributing to the crowdsale is very simple, it doesn't even require instantiating the contract. This is because the crowdsale responds to simple ether deposits, so anyone that sends ether to the crowdsale will automatically receive a reward. +Anyone can contribute to it by simply executing this command: + + var amount = web3.toWei(5, "ether") // decide how much to contribute + + eth.sendTransaction({from: eth.accounts[0], to: crowdsale.address, value: amount, gas: 1000000}) + + +Alternatively, if you want someone else to send it, they can even use the name registrar to contribute: + + eth.sendTransaction({from: eth.accounts[0], to: registrar.addr("mycrowdsale"), value: amount, gas: 500000}) + + +Now wait a minute for the blocks to pickup and you can check if the contract received the ether by doing any of these commands: + + web3.fromWei(crowdsale.amountRaised.call(), "ether") + " ether" + token.coinBalanceOf.call(eth.accounts[0]) + " tokens" + token.coinBalanceOf.call(crowdsale.address) + " tokens" + + +### Recover funds + +Once the deadline is passed someone has to wake up the contract to have the funds sent to either the beneficiary or back to the funders (if it failed). This happens because there is no such thing as an active loop or timer on ethereum so any future transactions must be pinged by someone. + + crowdsale.checkGoalReached.sendTransaction({from:eth.accounts[0], gas: 2000000}) + +You can check your accounts with these lines of code: + + web3.fromWei(eth.getBalance(eth.accounts[0]), "ether") + " ether" + web3.fromWei(eth.getBalance(eth.accounts[1]), "ether") + " ether" + token.coinBalanceOf.call(eth.accounts[0]) + " tokens" + token.coinBalanceOf.call(eth.accounts[1]) + " tokens" + +The crowdsale instance is setup to self destruct once it has done its job, so if the deadline is over and everyone got their prizes the contract is no more, as you can see by running this: + + eth.getCode(crowdsale.address) + +So you raised a 100 ethers and successfully distributed your original coin among the crowdsale donors. What could you do next with those things? + + + + + + +# Democracy DAO + + + +So far you have created a tradeable token and you successfully distributed it among all those who were willing to help fundraise a 100 ethers. That's all very interesting but what exactly are those tokens for? Why would anyone want to own or trade it for anything else valuable? If you can convince your new token is the next big money maybe others will want it, but so far your token offers no value per se. We are going to change that, by creating your first decentralized autonomous organization, or DAO. + +Think of the DAO as the constitution of a country, the executive branch of a government or maybe like a robotic manager for an organization. The DAO receives the money that your organization raises, keeps it safe and uses it to fund whatever its members want. The robot is incorruptible, will never defraud the bank, never create secret plans, never use the money for anything other than what its constituents voted on. The DAO will never disappear, never run away and cannot be controlled by anyone other than its own citizens. + +The token we distributed using the crowdsale is the only citizen document needed. Anyone who holds any token is able to create and vote on proposals. Similar to being a shareholder in a company, the token can be traded on the open market and the vote is proportional to amounts of tokens the voter holds. + +Take a moment to dream about the revolutionary possibilities this would allow, and now you can do it yourself, in under a 100 lines of code: + + +### The Code + + + + + contract token { mapping (address => uint) public coinBalanceOf; function token() { } function sendCoin(address receiver, uint amount) returns(bool sufficient) { } } + + + contract Democracy { + + uint public minimumQuorum; + uint public debatingPeriod; + token public voterShare; + address public founder; + Proposal[] public proposals; + uint public numProposals; + + event ProposalAdded(uint proposalID, address recipient, uint amount, bytes32 data, string description); + event Voted(uint proposalID, int position, address voter); + event ProposalTallied(uint proposalID, int result, uint quorum, bool active); + + struct Proposal { + address recipient; + uint amount; + bytes32 data; + string description; + uint creationDate; + bool active; + Vote[] votes; + mapping (address => bool) voted; + } + + struct Vote { + int position; + address voter; + } + + function Democracy(token _voterShareAddress, uint _minimumQuorum, uint _debatingPeriod) { + founder = msg.sender; + voterShare = token(_voterShareAddress); + minimumQuorum = _minimumQuorum || 10; + debatingPeriod = _debatingPeriod * 1 minutes || 30 days; + } + + + function newProposal(address _recipient, uint _amount, bytes32 _data, string _description) returns (uint proposalID) { + if (voterShare.coinBalanceOf(msg.sender)>0) { + proposalID = proposals.length++; + Proposal p = proposals[proposalID]; + p.recipient = _recipient; + p.amount = _amount; + p.data = _data; + p.description = _description; + p.creationDate = now; + p.active = true; + ProposalAdded(proposalID, _recipient, _amount, _data, _description); + numProposals = proposalID+1; + } + } + + function vote(uint _proposalID, int _position) returns (uint voteID){ + if (voterShare.coinBalanceOf(msg.sender)>0 && (_position >= -1 || _position <= 1 )) { + Proposal p = proposals[_proposalID]; + if (p.voted[msg.sender] == true) return; + voteID = p.votes.length++; + p.votes[voteID] = Vote({position: _position, voter: msg.sender}); + p.voted[msg.sender] = true; + Voted(_proposalID, _position, msg.sender); + } + } + + function executeProposal(uint _proposalID) returns (int result) { + Proposal p = proposals[_proposalID]; + /* Check if debating period is over */ + if (now > (p.creationDate + debatingPeriod) && p.active){ + uint quorum = 0; + /* tally the votes */ + for (uint i = 0; i < p.votes.length; ++i) { + Vote v = p.votes[i]; + uint voteWeight = voterShare.coinBalanceOf(v.voter); + quorum += voteWeight; + result += int(voteWeight) * v.position; + } + /* execute result */ + if (quorum > minimumQuorum && result > 0 ) { + p.recipient.call.value(p.amount)(p.data); + p.active = false; + } else if (quorum > minimumQuorum && result < 0) { + p.active = false; + } + ProposalTallied(_proposalID, result, quorum, p.active); + } + } + } + + + + + +There's a lot of going on but it's simpler than it looks. The rules of your organization are very simple: anyone with at least one token can create proposals to send funds from the country's account. After a week of debate and votes, if it has received votes worth a total of 100 tokens or more and has more approvals than rejections, the funds will be sent. If the quorum hasn't been met or it ends on a tie, then voting is kept until it's resolved. Otherwise, the proposal is locked and kept for historical purposes. + +So let's recap what this means: in the last two sections you created 10,000 tokens, sent 1,000 of those to another account you control, 2,000 to a friend named Alice and distributed 5,000 of them via a crowdsale. This means that you no longer control over 50% of the votes in the DAO, and if Alice and the community bands together, they can outvote any spending decision on the 100 ethers raised so far. This is exactly how a democracy should work. If you don't want to be a part of your country anymore the only thing you can do is sell your own tokens on a decentralized exchange and opt out, but you cannot prevent the others from doing so. + + +### Set Up your Organization + +So open your console and let's get ready to finally put your country online. First, let's set the right parameters, pick them with care: + + var _voterShareAddress = token.address; + var _minimumQuorum = 10; // Minimun amount of voter tokens the proposal needs to pass + var _debatingPeriod = 60; // debating period, in minutes; + +With these default parameters anyone with any tokens can make a proposal on how to spend the organization's money. The proposal has 1 hour to be debated and it will pass if it has at least votes from at least 0.1% of the total tokens and has more support than rejections. Pick those parameters with care, as you won't be able to change them in the future. + + var daoCompiled = eth.compile.solidity('contract token { mapping (address => uint) public coinBalanceOf; function token() { } function sendCoin(address receiver, uint amount) returns(bool sufficient) { } } contract Democracy { uint public minimumQuorum; uint public debatingPeriod; token public voterShare; address public founder; Proposal[] public proposals; uint public numProposals; event ProposalAdded(uint proposalID, address recipient, uint amount, bytes32 data, string description); event Voted(uint proposalID, int position, address voter); event ProposalTallied(uint proposalID, int result, uint quorum, bool active); struct Proposal { address recipient; uint amount; bytes32 data; string description; uint creationDate; bool active; Vote[] votes; mapping (address => bool) voted; } struct Vote { int position; address voter; } function Democracy(token _voterShareAddress, uint _minimumQuorum, uint _debatingPeriod) { founder = msg.sender; voterShare = token(_voterShareAddress); minimumQuorum = _minimumQuorum || 10; debatingPeriod = _debatingPeriod * 1 minutes || 30 days; } function newProposal(address _recipient, uint _amount, bytes32 _data, string _description) returns (uint proposalID) { if (voterShare.coinBalanceOf(msg.sender)>0) { proposalID = proposals.length++; Proposal p = proposals[proposalID]; p.recipient = _recipient; p.amount = _amount; p.data = _data; p.description = _description; p.creationDate = now; p.active = true; ProposalAdded(proposalID, _recipient, _amount, _data, _description); numProposals = proposalID+1; } else { return 0; } } function vote(uint _proposalID, int _position) returns (uint voteID){ if (voterShare.coinBalanceOf(msg.sender)>0 && (_position >= -1 || _position <= 1 )) { Proposal p = proposals[_proposalID]; if (p.voted[msg.sender] == true) return; voteID = p.votes.length++; Vote v = p.votes[voteID]; v.position = _position; v.voter = msg.sender; p.voted[msg.sender] = true; Voted(_proposalID, _position, msg.sender); } else { return 0; } } function executeProposal(uint _proposalID) returns (int result) { Proposal p = proposals[_proposalID]; /* Check if debating period is over */ if (now > (p.creationDate + debatingPeriod) && p.active){ uint quorum = 0; /* tally the votes */ for (uint i = 0; i < p.votes.length; ++i) { Vote v = p.votes[i]; uint voteWeight = voterShare.coinBalanceOf(v.voter); quorum += voteWeight; result += int(voteWeight) * v.position; } /* execute result */ if (quorum > minimumQuorum && result > 0 ) { p.recipient.call.value(p.amount)(p.data); p.active = false; } else if (quorum > minimumQuorum && result < 0) { p.active = false; } } ProposalTallied(_proposalID, result, quorum, p.active); } }'); + + var democracyContract = web3.eth.contract(daoCompiled.Democracy.info.abiDefinition); + + var democracy = democracyContract.new( + _voterShareAddress, + _minimumQuorum, + _debatingPeriod, + { + from:web3.eth.accounts[0], + data:daoCompiled.Democracy.code, + gas: 3000000 + }, function(e, contract){ + if(!e) { + + if(!contract.address) { + console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); + + } else { + console.log("Contract mined! Address: " + contract.address); + console.log(contract); + } + + } + }) + +**If you are using the _online compiler_ Copy the contract code to the [online solidity compiler](https://chriseth.github.io/cpp-ethereum/), and then grab the content of the box labeled **Geth Deploy**. Since you have already set the parameters, you don't need to change anything to that text, simply paste the resulting text on your geth window.** + +Wait a minute until the miners pick it up. It will cost you about 850k Gas. Once that is picked up, it's time to instantiate it and set it up, by pointing it to the correct address of the token contract you created previously. + +If everything worked out, you can take a look at the whole organization by executing this string: + + "This organization has " + democracy.numProposals() + " proposals and uses the token at the address " + democracy.voterShare() ; + +If everything is setup then your DAO should return a proposal count of 0 and an address marked as the "founder". While there are still no proposals, the founder of the DAO can change the address of the token to anything it wants. + +### Register your organization name + +Let's also register a name for your contract so it's easily accessible (don't forget to check your name availability with registrar.addr("nameYouWant") before reserving!) + + var name = "MyPersonalDemocracy" + registrar.reserve.sendTransaction(name, {from: eth.accounts[0]}) + var democracy = eth.contract(daoCompiled.Democracy.info.abiDefinition).at(democracy.address); + democracy.setup.sendTransaction(registrar.addr("MyFirstCoin"),{from:eth.accounts[0]}) + +Wait for the previous transactions to be picked up and then: + + registrar.setAddress.sendTransaction(name, democracy.address, true,{from: eth.accounts[0]}); + + +### The Democracy Watchbots + + + var event = democracy.ProposalAdded({}, '', function(error, result){ + if (!error) + console.log("New Proposal #"+ result.args.proposalID +"!\n Send " + web3.fromWei(result.args.amount, "ether") + " ether to " + result.args.recipient.substring(2,8) + "... for " + result.args.description ) + }); + var eventVote = democracy.Voted({}, '', function(error, result){ + if (!error) + var opinion = ""; + if (result.args.position > 0) { + opinion = "in favor" + } else if (result.args.position < 0) { + opinion = "against" + } else { + opinion = "abstaining" + } + + console.log("Vote on Proposal #"+ result.args.proposalID +"!\n " + result.args.voter + " is " + opinion ) + }); + var eventTally = democracy.ProposalTallied({}, '', function(error, result){ + if (!error) + var totalCount = ""; + if (result.args.result > 1) { + totalCount = "passed" + } else if (result.args.result < 1) { + totalCount = "rejected" + } else { + totalCount = "a tie" + } + console.log("Votes counted on Proposal #"+ result.args.proposalID +"!\n With a total of " + Math.abs(result.args.result) + " out of " + result.args.quorum + ", proposal is " + totalCount + ". Proposal is " + (result.args.active? " still on the floor" : "archived") ) + }); + + +### Interacting with the DAO + +After you are satisfied with what you want, it's time to get all that ether you got from the crowdfunding into your new organization: + + eth.sendTransaction({from: eth.accounts[1], to: democracy.address, value: web3.toWei(100, "ether")}) + +This should take only a minute and your country is ready for business! Now, as a first priority, your organisation needs a nice logo, but unless you are a designer, you have no idea how to do that. For the sake of argument let's say you find that your friend Bob is a great designer who's willing to do it for only 10 ethers, so you want to propose to hire him. + + recipient = registrar.addr("bob"); + amount = web3.toWei(10, "ether"); + shortNote = "Logo Design"; + + democracy.newProposal.sendTransaction( recipient, amount, '', shortNote, {from: eth.accounts[0], gas:1000000}) + +After a minute, anyone can check the proposal recipient and amount by executing these commands: + + "This organization has " + (Number(democracy.numProposals())+1) + " pending proposals"; + +### Keep an eye on the organization + +Unlike most governments, your country's government is completely transparent and easily programmable. As a small demonstration here's a snippet of code that goes through all the current proposals and prints what they are and for whom: + + + + function checkAllProposals() { + console.log("Country Balance: " + web3.fromWei( eth.getBalance(democracy.address), "ether") ); + for (i = 0; i< (Number(democracy.numProposals())); i++ ) { + var p = democracy.proposals(i); + var timeleft = Math.floor(((Math.floor(Date.now() / 1000)) - Number(p[4]) - Number(democracy.debatingPeriod()))/60); + console.log("Proposal #" + i + " Send " + web3.fromWei( p[1], "ether") + " ether to address " + p[0].substring(2,6) + " for "+ p[3] + ".\t Deadline:"+ Math.abs(Math.floor(timeleft)) + (timeleft>0?" minutes ago ":" minutes left ") + (p[5]? " Active":" Archived") ); + } + } + + checkAllProposals(); + +A concerned citizen could easily write a bot that periodically pings the blockchain and then publicizes any new proposals that were put forth, guaranteeing total transparency. + +Now of course you want other people to be able to vote on your proposals. You can check the crowdsale tutorial on the best way to register your contract app so that all the user needs is a name, but for now let's use the easier version. Anyone should be able to instantiate a local copy of your country in their computer by using this giant command: + + + democracy = eth.contract( [{ constant: true, inputs: [{ name: '', type: 'uint256' } ], name: 'proposals', outputs: [{ name: 'recipient', type: 'address' }, { name: 'amount', type: 'uint256' }, { name: 'data', type: 'bytes32' }, { name: 'descriptionHash', type: 'bytes32' }, { name: 'creationDate', type: 'uint256' }, { name: 'numVotes', type: 'uint256' }, { name: 'quorum', type: 'uint256' }, { name: 'active', type: 'bool' } ], type: 'function' }, { constant: false, inputs: [{ name: '_proposalID', type: 'uint256' } ], name: 'executeProposal', outputs: [{ name: 'result', type: 'uint256' } ], type: 'function' }, { constant: true, inputs: [ ], name: 'debatingPeriod', outputs: [{ name: '', type: 'uint256' } ], type: 'function' }, { constant: true, inputs: [ ], name: 'numProposals', outputs: [{ name: '', type: 'uint256' } ], type: 'function' }, { constant: true, inputs: [ ], name: 'founder', outputs: [{ name: '', type: 'address' } ], type: 'function' }, { constant: false, inputs: [{ name: '_proposalID', type: 'uint256' }, { name: '_position', type: 'int256' } ], name: 'vote', outputs: [{ name: 'voteID', type: 'uint256' } ], type: 'function' }, { constant: false, inputs: [{ name: '_voterShareAddress', type: 'address' } ], name: 'setup', outputs: [ ], type: 'function' }, { constant: false, inputs: [{ name: '_recipient', type: 'address' }, { name: '_amount', type: 'uint256' }, { name: '_data', type: 'bytes32' }, { name: '_descriptionHash', type: 'bytes32' } ], name: 'newProposal', outputs: [{ name: 'proposalID', type: 'uint256' } ], type: 'function' }, { constant: true, inputs: [ ], name: 'minimumQuorum', outputs: [{ name: '', type: 'uint256' } ], type: 'function' }, { inputs: [ ], type: 'constructor' } ] ).at(registrar.addr('MyPersonalCountry')) + +Then anyone who owns any of your tokens can vote on the proposals by doing this: + + var proposalID = 0; + var position = -1; // +1 for voting yea, -1 for voting nay, 0 abstains but counts as quorum + democracy.vote.sendTransaction(proposalID, position, {from: eth.accounts[0], gas: 1000000}); + + var proposalID = 1; + var position = 1; // +1 for voting yea, -1 for voting nay, 0 abstains but counts as quorum + democracy.vote.sendTransaction(proposalID, position, {from: eth.accounts[0], gas: 1000000}); + + +Unless you changed the basic parameters in the code, any proposal will have to be debated for at least a week until it can be executed. After that anyone—even a non-citizen—can demand the votes to be counted and the proposal to be executed. The votes are tallied and weighted at that moment and if the proposal is accepted then the ether is sent immediately and the proposal is archived. If the votes end in a tie or the minimum quorum hasn’t been reached, the voting is kept open until the stalemate is resolved. If it loses, then it's archived and cannot be voted again. + + var proposalID = 1; + democracy.executeProposal.sendTransaction(proposalID, {from: eth.accounts[0], gas: 1000000}); + + +If the proposal passed then you should be able to see Bob's ethers arriving on his address: + + web3.fromWei(eth.getBalance(democracy.address), "ether") + " ether"; + web3.fromWei(eth.getBalance(registrar.addr("bob")), "ether") + " ether"; + + +**Try for yourself:** This is a very simple democracy contract, which could be vastly improved: currently, all proposals have the same debating time and are won by direct vote and simple majority. Can you change that so it will have some situations, depending on the amount proposed, that the debate might be longer or that it would require a larger majority? Also think about some way where citizens didn't need to vote on every issue and could temporarily delegate their votes to a special representative. You might have also noticed that we added a tiny description for each proposal. This could be used as a title for the proposal or could be a hash of a larger document describing it in detail. + +### Let's go exploring! + +You have reached the end of this tutorial, but it's just the beginning of a great adventure. Look back and see how much you accomplished: you created a living, talking robot, your own cryptocurrency, raised funds through a trustless crowdfunding and used it to kickstart your own personal democratic organization. + +For the sake of simplicity, we only used the democratic organization you created to send ether around, the native currency of ethereum. While that might be good enough for some, this is only scratching the surface of what can be done. In the ethereum network contracts have all the same rights as any normal user, meaning that your organization could do any of the transactions that you executed coming from your own accounts. + + +### What could happen next? + +* The greeter contract you created at the beginning could be improved to charge ether for its services and could funnel those funds into the DAO. + +* The tokens you still control could be sold on a decentralized exchange or traded for goods and services to fund further develop the first contract and grow the organization. + +* Your DAO could own its own name on the name registrar, and then change where it's redirecting in order to update itself if the token holders approved. + +* The organization could hold not only ethers, but any kind of other coin created on ethereum, including assets whose value are tied to the bitcoin or dollar. + +* The DAO could be programmed to allow a proposal with multiple transactions, some scheduled to the future. +It could also own shares of other DAO's, meaning it could vote on larger organization or be a part of a federation of DAO's. + +* The Token Contract could be reprogrammed to hold ether or to hold other tokens and distribute it to the token holders. This would link the value of the token to the value of other assets, so paying dividends could be accomplished by simply moving funds to the token address. + +This all means that this tiny society you created could grow, get funding from third parties, pay recurrent salaries, own any kind of crypto-assets and even use crowdsales to fund its activities. All with full transparency, complete accountability and complete immunity from any human interference. While the network lives the contracts will execute exactly the code they were created to execute, without any exception, forever. + +So what will your contract be? Will it be a country, a company, a non-profit group? What will your code do? + +That's up to you. diff --git a/docs/Creating-your-own-Ethereum-apps-using-Eth-go.md b/docs/Creating-your-own-Ethereum-apps-using-Eth-go.md new file mode 100644 index 0000000000..d5777578f0 --- /dev/null +++ b/docs/Creating-your-own-Ethereum-apps-using-Eth-go.md @@ -0,0 +1,115 @@ +The modular nature of Go and the Ethereum Go implementation, [eth-go](https://github.com/ethereum/eth-go), make it very easy to build your own Ethereum native applications. + +This post will cover the minimal steps required to build an native Ethereum application. + +Ethereum comes with a global config found in the [ethutil](https://github.com/ethereum/eth-go/tree/master/ethutil) package. The global config requires you to set a base path to store it's files (database, settings, etc). + +```go +func main() { + // Read config + ethutil.ReadConfig(".test", ethutil.LogStd, nil, "MyEthApp") +} +``` + +ReadConfig takes four arguments. The data folder to use, a log flag, a globalConf instance and an id string to identify your app to other nodes in the network. + +Once you've configured the global config you can set up and create your Ethereum node. The Ethereum Object, or Node, will handle all trafic from and to the Ethereum network as well as handle all incoming block and transactions. A new node can be created through the `new` method found in [eth-go](https://github.com/ethereum/eth-go). + +```go +func main() { + // Read config + ethutil.ReadConfig(".test", ethutil.LogStd, nil, "MyEthApp") + + // Create a new ethereum node + ethereum, err := eth.New(eth.CapDefault, false) + if err != nil { + panic(fmt.Sprintf("Could not start node: %s\n", err)) + } + // Set the port (default 30303) + ethereum.Port = "10101" + // Once we reach max, bounce them off. + ethereum.MaxPeers = 10 +} +``` + +New requires two arguments; the capabilities of the node and whether or not to use UPNP for port-forwarding. If you don't want to fallback to client-only features set an Ethereum port and the max amount of peers this node can connect to. + +In order to identify the node to the network you'll be required to create a private key. The easiest way to create a new keypair is by using the `KeyRing` found in the `ethutil` package. + +```go +func main() { + // Read config + ethutil.ReadConfig(".test", ethutil.LogStd, nil, "MyEthApp") + + // Create a new ethereum node + ethereum, err := eth.New(eth.CapDefault, false) + if err != nil { + panic(fmt.Sprintf("Could not start node: %s\n", err)) + } + // Set the port (default 30303) + ethereum.Port = "10101" + // Once we reach max, bounce them off. + ethereum.MaxPeers = 10 + + keyRing := ethutil.GetKeyRing() + // Create a new key if non exist + if keyRing.Len() == 0 { + // Create a new keypair + keyPair, err := ethutil.GenerateNewKeyPair() + if err != nil { + panic(err) + } + + // Add the keypair to the key ring + keyRing.Add(keyPair) + } +} +``` + +Once the base Ethereum stack has been set up it's time to fire up its engines and connect to the main network. + +```go +package main + +import ( + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethutil" +) + +func main() { + // Read config + ethutil.ReadConfig(".test", ethutil.LogStd, nil, "MyEthApp") + + // Create a new ethereum node + ethereum, err := eth.New(eth.CapDefault, false) + if err != nil { + panic(fmt.Sprintf("Could not start node: %s\n", err)) + } + // Set the port (default 30303) + ethereum.Port = "10101" + // Once we reach max, bounce them off. + ethereum.MaxPeers = 10 + + keyRing := ethutil.GetKeyRing() + // Create a new key if non exist + if keyRing.Len() == 0 { + // Create a new keypair + keyPair, err := ethutil.GenerateNewKeyPair() + if err != nil { + panic(err) + } + + // Add the keypair to the key ring + keyRing.Add(keyPair) + } + + ethereum.Start(true) + ethereum.WaitForShutdown() +} +``` + +`ethereum.Start()` takes one argument, whether or not we want to connect to one of the known seed nodes. If you want your own little testnet-in-a-box you can disable it else set it to true. + +Your node should now be catching up with the blockchain. From here on out you are on your own. You could create a reactor to listen to specific events or just dive into the chain state directly. If you want to look at some example code you can check [DNSEth here.](https://github.com/maran/dnseth) + +Have fun! \ No newline at end of file diff --git a/docs/Cross-compiling-Ethereum.md b/docs/Cross-compiling-Ethereum.md new file mode 100644 index 0000000000..4faa52044e --- /dev/null +++ b/docs/Cross-compiling-Ethereum.md @@ -0,0 +1,164 @@ +**Note: All of these and much more have been merged into the project Makefile. +You can cross build via `make geth--` without needing to know any +of these details from below.** + +Developers usually have a preferred platform that they feel most comfortable +working in, with all the necessary tools, libraries and environments set up for +an optimal workflow. However, there's often need to build for either a different +CPU architecture, or an entirely different operating system; but maintaining a +development environment for each and switching between the them quickly becomes +unwieldy. + +Here we present a very simple way to cross compile Ethereum to various operating +systems and architectures using a minimal set of prerequisites and a completely +containerized approach, guaranteeing that your development environment remains +clean even after the complex requirements and mechanisms of a cross compilation. + +The currently supported target platforms are: + + - ARMv7 Android and iOS + - 32 bit, 64 bit and ARMv5 Linux + - 32 bit and 64 bit Mac OSX + - 32 bit and 64 bit Windows + +Please note, that cross compilation does not replace a release build. Although +resulting binaries can usually run perfectly on the desired platform, compiling +on a native system with the specialized tools provided by the official vendor +can often result in more a finely optimized code. + +## Cross compilation environment + +Although the `go-ethereum` project is written in Go, it does include a bit of C +code shared between all implementations to ensure that all perform equally well, +including a dependency to the GNU Multiple Precision Arithmetic Library. Because +of these, Go cannot by itself compile to a different platform than the host. To +overcome this limitation, we will use [`xgo`](https://github.com/karalabe/xgo), +a Go cross compiler package based on Docker containers that has been architected +specifically to allow both embedded C snippets as well as simpler external C +dependencies during compilation. + +The `xgo` project has two simple dependencies: Docker (to ensure that the build +environment is completely contained) and Go. On most platforms these should be +available from the official package repositories. For manually installing them, +please consult their install guides at [Docker](https://docs.docker.com/installation/) +and [Go](https://golang.org/doc/install) respectively. This guide assumes that these +two dependencies are met. + +To install and/or update xgo, simply type: + + $ go get -u github.com/karalabe/xgo + +You can test whether `xgo` is functioning correctly by requesting it to cross +compile itself and verifying that all cross compilations succeeded or not. + + $ xgo github.com/karalabe/xgo + ... + + $ ls -al + -rwxr-xr-x 1 root root 2792436 Sep 14 16:45 xgo-android-21-arm + -rwxr-xr-x 1 root root 2353212 Sep 14 16:45 xgo-darwin-386 + -rwxr-xr-x 1 root root 2906128 Sep 14 16:45 xgo-darwin-amd64 + -rwxr-xr-x 1 root root 2388288 Sep 14 16:45 xgo-linux-386 + -rwxr-xr-x 1 root root 2960560 Sep 14 16:45 xgo-linux-amd64 + -rwxr-xr-x 1 root root 2437864 Sep 14 16:45 xgo-linux-arm + -rwxr-xr-x 1 root root 2551808 Sep 14 16:45 xgo-windows-386.exe + -rwxr-xr-x 1 root root 3130368 Sep 14 16:45 xgo-windows-amd64.exe + + +## Building Ethereum + +Cross compiling Ethereum is analogous to the above example, but an additional +flags is required to satisfy the dependencies: + + - `--deps` is used to inject arbitrary C dependency packages and pre-build them + +Injecting the GNU Arithmetic Library dependency and selecting `geth` would be: + + $ xgo --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 \ + github.com/ethereum/go-ethereum/cmd/geth + ... + + $ ls -al + -rwxr-xr-x 1 root root 23213372 Sep 14 17:59 geth-android-21-arm + -rwxr-xr-x 1 root root 14373980 Sep 14 17:59 geth-darwin-386 + -rwxr-xr-x 1 root root 17373676 Sep 14 17:59 geth-darwin-amd64 + -rwxr-xr-x 1 root root 21098910 Sep 14 17:59 geth-linux-386 + -rwxr-xr-x 1 root root 25049693 Sep 14 17:59 geth-linux-amd64 + -rwxr-xr-x 1 root root 20578535 Sep 14 17:59 geth-linux-arm + -rwxr-xr-x 1 root root 16351260 Sep 14 17:59 geth-windows-386.exe + -rwxr-xr-x 1 root root 19418071 Sep 14 17:59 geth-windows-amd64.exe + + +As the cross compiler needs to build all the dependencies as well as the main +project itself for each platform, it may take a while for the build to complete +(approximately 3-4 minutes on a Core i7 3770K machine). + +### Fine tuning the build + +By default Go, and inherently `xgo`, checks out and tries to build the master +branch of a source repository. However, more often than not, you'll probably +want to build a different branch from possibly an entirely different remote +repository. These can be controlled via the `--remote` and `--branch` flags. + +To build the `develop` branch of the official `go-ethereum` repository instead +of the default `master` branch, you just need to specify it as an additional +command line flag (`--branch`): + + $ xgo --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 \ + --branch=develop \ + github.com/ethereum/go-ethereum/cmd/geth + +Additionally, during development you will most probably want to not only build +a custom branch, but also one originating from your own fork of the repository +instead of the upstream one. This can be done via the `--remote` flag: + + $ xgo --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 \ + --remote=https://github.com/karalabe/go-ethereum \ + --branch=rpi-staging \ + github.com/ethereum/go-ethereum/cmd/geth + +By default `xgo` builds binaries for all supported platforms and architectures, +with Android binaries defaulting to the highest released Android NDK platform. +To limit the build targets or compile to a different Android platform, use the +`--targets` CLI parameter. + + $ xgo --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 \ + --targets=android-16/arm,windows/* \ + github.com/ethereum/go-ethereum/cmd/geth + +### Building locally + +If you would like to cross compile your local development version, simply specify +a local path (starting with `.` or `/`), and `xgo` will use all local code from +`GOPATH`, only downloading missing dependencies. In such a case of course, the +`--branch`, `--remote` and `--pkg` arguments are no-op: + + $ xgo --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 \ + ./cmd/geth + +## Using the Makefile + +Having understood the gist of `xgo` based cross compilation, you do not need to +actually memorize and maintain these commands, as they have been incorporated into +the official [Makefile](https://github.com/ethereum/go-ethereum/blob/master/Makefile) +and can be invoked with a trivial `make` request: + + * `make geth-cross`: Cross compiles to every supported OS and architecture + * `make geth-`: Cross compiles supported architectures of a particular OS (e.g. `linux`) + * `make geth--`: Cross compiles to a specific OS/architecture (e.g. `linux`, `arm`) + +We advise using the `make` based commands opposed to manually invoking `xgo` as we do +maintain the Makefile actively whereas we cannot guarantee that this document will be +always readily updated to latest advancements. + +### Tuning the cross builds + +A few of the `xgo` build options have also been surfaced directly into the Makefile to +allow fine tuning builds to work around either upstream Go issues, or to enable some +fancier mechanics. + + - `make ... GO=`: Use a specific Go runtime (e.g. `1.5.1`, `1.5-develop`, `develop`) + - `make ... MODE=`: Build a specific target type (e.g. `exe`, `c-archive`). + +Please note that these are not yet fully finalized, so they may or may not change in +the future as our code and the Go runtime features change. \ No newline at end of file diff --git a/docs/Developer-Guide.md b/docs/Developer-Guide.md new file mode 100644 index 0000000000..99ba441829 --- /dev/null +++ b/docs/Developer-Guide.md @@ -0,0 +1,21 @@ +### Native DApps + +[Introduction and packages](https://github.com/ethereum/go-ethereum/wiki/Native:-Introduction) + +[Account management](https://github.com/ethereum/go-ethereum/wiki/Native:-Account-management) + +### Mobile platforms + +[Introduction and packages](https://github.com/ethereum/go-ethereum/wiki/Mobile:-Introduction) + +[Account management](https://github.com/ethereum/go-ethereum/wiki/Mobile:-Account-management) + +### Transaction tracing + +[Introduction and basics](https://github.com/ethereum/go-ethereum/wiki/Tracing:-Introduction) + +[Custom in-node tracers](https://github.com/ethereum/go-ethereum/wiki/Tracing:-Custom-tracers) + +[Full blockchain tracing](https://github.com/ethereum/go-ethereum/wiki/Tracing:-Blockchain-tracing) + +[Dependency exfiltration](https://github.com/ethereum/go-ethereum/wiki/Tracing:-Exfiltration) \ No newline at end of file diff --git a/docs/Developers'-Guide.md b/docs/Developers'-Guide.md new file mode 100644 index 0000000000..b7e7484b69 --- /dev/null +++ b/docs/Developers'-Guide.md @@ -0,0 +1,138 @@ +**NOTE: These instructions are for people who want to contribute Go source code changes. +If you just want to run ethereum, use the normal [Installation Instructions](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum)** + +This document is the entry point for developers of the Go implementation of Ethereum. Developers here refer to the hands-on: who are interested in build, develop, debug, submit a bug report or pull request or contribute code to go-ethereum. + +## Building and Testing + +### Go Environment + +We assume that you have [`go` v1.8 installed](https://github.com/ethereum/go-ethereum/wiki/Installing-Go), and `GOPATH` is set. + +**Note**:You must have your working copy under `$GOPATH/src/github.com/ethereum/go-ethereum`. + +Since `go` does not use relative path for import, working in any other directory will have no effect, since the import paths will be appended to `$GOPATH/src`, and if the lib does not exist, the version at master HEAD will be downloaded. + +Most likely you will be working from your fork of `go-ethereum`, let's say from `github.com/nirname/go-ethereum`. Clone or move your fork into the right place: + +``` +git clone git@github.com:nirname/go-ethereum.git $GOPATH/src/github.com/ethereum/go-ethereum +``` + +### Managing Vendored Dependencies + +All other dependencies are tracked in the vendor/ directory. We use [govendor](https://github.com/kardianos/govendor) to manage them. + +If you want to add a new dependency, run `govendor fetch `, then commit the result. + +If you want to update all dependencies to their latest upstream version, run `govendor fetch +v`. + +You can also use govendor to run certain commands on all go-ethereum packages, excluding vendored +code. Example: to recreate all generated code, run `govendor generate +l`. + +### Building Executables + +Switch to the go-ethereum repository root directory. + +You can build all code using the go tool, placing the resulting binary in `$GOPATH/bin`. + +```text +go install -v ./... +``` + +go-ethereum exectuables can be built individually. To build just geth, use: + +```text +go install -v ./cmd/geth +``` + +Read about cross compilation of go-ethereum [here](https://github.com/ethereum/go-ethereum/wiki/Cross-compiling-Ethereum). + +### Git flow + +To make life easier try [git flow](http://nvie.com/posts/a-successful-git-branching-model/) it sets this all up and streamlines your work flow. + +### Testing + +Testing one library: + +``` +go test -v -cpu 4 ./eth +``` + +Using options `-cpu` (number of cores allowed) and `-v` (logging even if no error) is recommended. + +Testing only some methods: + +``` +go test -v -cpu 4 ./eth -run TestMethod +``` + +**Note**: here all tests with prefix _TestMethod_ will be run, so if you got TestMethod, TestMethod1, then both! + +Running benchmarks, eg.: + +``` +go test -v -cpu 4 -bench . -run BenchmarkJoin +``` + +for more see [go test flags](http://golang.org/cmd/go/#hdr-Description_of_testing_flags) + +### Metrics and monitoring + +`geth` can do node behaviour monitoring, aggregation and show performance metric charts. +Read about [metrics and monitoring](https://github.com/ethereum/go-ethereum/wiki/Metrics-and-Monitoring) + +### Getting Stack Traces + +If `geth` is started with the `--pprof` option, a debugging HTTP server is made available on port 6060. You can bring up http://localhost:6060/debug/pprof to see the heap, running routines etc. By clicking full goroutine stack dump (clicking http://localhost:6060/debug/pprof/goroutine?debug=2) you can generate trace that is useful for debugging. + +Note that if you run multiple instances of `geth`, this port will only work for the first instance that was launched. If you want to generate stacktraces for these other instances, you need to start them up choosing an alternative pprof port. Make sure you are redirecting stderr to a logfile. + +``` +geth -port=30300 -verbosity 5 --pprof --pprofport 6060 2>> /tmp/00.glog +geth -port=30301 -verbosity 5 --pprof --pprofport 6061 2>> /tmp/01.glog +geth -port=30302 -verbosity 5 --pprof --pprofport 6062 2>> /tmp/02.glog +``` + +Alternatively if you want to kill the clients (in case they hang or stalled syncing, etc) but have the stacktrace too, you can use the `-QUIT` signal with `kill`: + +``` +killall -QUIT geth +``` + +This will dump stack traces for each instance to their respective log file. + +## Contributing + +Thank you for considering to help out with the source code! We welcome contributions from +anyone on the internet, and are grateful for even the smallest of fixes! + +GitHub is used to track issues and contribute code, suggestions, feature requests or +documentation. + +If you'd like to contribute to go-ethereum, please fork, fix, commit and send a pull +request (PR) for the maintainers to review and merge into the main code base. If you wish +to submit more complex changes though, please check up with the core devs first on [our +gitter channel](https://gitter.im/ethereum/go-ethereum) to ensure those changes are in +line with the general philosophy of the project and/or get some early feedback which can +make both your efforts much lighter as well as our review and merge procedures quick and +simple. + +PRs need to be based on and opened against the `master` branch (unless by explicit +agreement, you contribute to a complex feature branch). + +Your PR will be reviewed according to the [Code Review +Guidelines](https://github.com/ethereum/go-ethereum/wiki/Code-Review-Guidelines). + +We encourage a PR early approach, meaning you create the PR the earliest even without the +fix/feature. This will let core devs and other volunteers know you picked up an issue. +These early PRs should indicate 'in progress' status. + +## Dev Tutorials (mostly outdated) + +* [Private networks, local clusters and monitoring](https://github.com/ethereum/go-ethereum/wiki/Setting-up-private-network-or-local-cluster) + +* [P2P 101](https://github.com/ethereum/go-ethereum/wiki/Peer-to-Peer): a tutorial about setting up and creating a p2p server and p2p sub protocol. + +* [How to Whisper](https://github.com/ethereum/go-ethereum/wiki/How-to-Whisper): an introduction to whisper. diff --git a/docs/Diagnostic-Tool-wnode.md b/docs/Diagnostic-Tool-wnode.md new file mode 100644 index 0000000000..087afdcd84 --- /dev/null +++ b/docs/Diagnostic-Tool-wnode.md @@ -0,0 +1,239 @@ +## Wnode + +Wnode (whisper node) is a command-line diagnostic tool. It does not have a nice user interface, because its main purpose is diagnostic, and it's meant to be very light-weight rather than beautiful. Wnode might be used for different purposes, including: + +- running a standalone bootstrap node, in order to set up a private whisper network +- connecting to particular node for debugging or other purposes +- engaging in command-line chat with another peer in order to test its functionality +- sending and receiving text messages +- sending and receiving files +- running fully functional mail server +- testing functionality of mail client + +#### Usage + + > wnode [flags/arguments] + +For example: + + > wnode -forwarder -standalone -ip=127.0.0.1:30381 -idfile=config.txt -mailserver -dbpath=tmp/db + +#### Flags + +-asym: use asymmetric encryption in the chat + +-fileexchange: file exchange mode (send and receive files instead of text messages) + +-forwarder: forwarder mode (only forward; neither send nor decrypt messages) + +-mailserver: mail server mode (delivers expired messages on demand) + +-mailclient: request expired messages from the mail server + +-standalone: don't actively connect to any peers, wait for incoming connections instead + +-test: use of predefined parameters for diagnostics, including passwords + +-generatekey: generate a new private key (ECIES) and exit + +#### Arguments + +In case of missing arguments wnode will either use default value or ask you to provide them. For security reasons, you can not provide passwords in command-line arguments. Only in test mode hardcoded passwords are used. + +-verbosity: +Verbosity level of logging. Int value between 0 and 5. Default value 1. For example: -verbosity=5. + +-ttl: +Time-to-live for messages in seconds. Default value 30. For example: -ttl=20. + +-maxsize: +Maximum allowed message size in bytes. + +-work: +Maximum time in seconds allowed to spend on proof of work in order to achieve the target (set by 'pow' argument). + +-pow: +PoW target for normal messages in float format (e.g. -pow=2.7). + +-mspow: +PoW requirement for Mail Server request. + +-ip: +IP address and port of this node (e.g. 127.0.0.1:30303). + +-pub: +Public key of your peer (for asymmetric encryption). For example: +-pub=0x07af49cbe6353b8732a8b9eb20dd1472f3d4512cd1a11382ee2817cc6de9453bc07c32c730b93bc83877b11e4f47d718751297f4edcbf35015df2b34ff5fc6a75d + +-idfile: +File name containing node ID (private key) in hexadecimal string format. +For example: -idfile=/home/vlad/tmp/config +Example of the file content: b3651aff593ef395ee7c16f3ca681830f7d8d0b2729cf472b14f2c4ebe833aa0 + +-boot: +The bootstrap node you want to connect to. For example: +-boot=enode://d25474361659861e9e651bc728a17e807a3359ca0d344afd544ed0f11a31faecaf4d74b55db53c6670fd624f08d5c79adfc8da5dd4a11b9213db49a3b750845e@52.178.209.125:30379 + +-topic: +Message topic in hexadecimal format. For example: -topic=70a4beef. + +-dbpath: +Path to directory where Mail Server will store the incoming messages. +For example: -dbpath=tmp/myfiles/archive + +-savedir: +Directory where successfully decrypted incoming messages will be saved as files in plain format. +Message hashes will be used as file names in order to avoid collisions. +By default, only big messages are stored there. +In 'fileexchange' mode all messages are stored there. + +### Scenarios & Examples + +For simplicity, in these examples we assume that we only use wnode to communicate with another wnode. + +#### Start a bootstrap node for test network + + > wnode -standalone -forwarder -ip=127.0.0.1:30379 + +result output: + + my public key: 0x040ef7acd60781c336c52056b3782f7eae45be2063e591ac6b78472dc27ba770010bde445ffd2f3623ad656f3859e00d11ef518df4916c4d4e258c60b15f34c682 enode://15454fc65bbf0031155f4eee83fa732f1454c314e9f78ade9cba4d4a098d29edbf5431764ee65b200169025c3f900cacc3348a000dda7a8a0d9643d0b7618712@127.0.0.1:30379 + Bootstrap Whisper node started + +After the bootstrap node has started, another local node can connect to it, using the resulting enode: + + > wnode -test -boot=enode://15454fc65bbf0031155f4eee83fa732f1454c314e9f78ade9cba4d4a098d29edbf5431764ee65b200169025c3f900cacc3348a000dda7a8a0d9643d0b7618712@127.0.0.1:30379 + +result output: + + ............................ + Whisper node started + Connected to peer. + ............................ + +Now, if you restart you bootstrap node, its enode will be different, because new ID will be randomly generated. If you need to repeat the tests multiple times, it will be extremely boring to copy and paste new enode every time you restart. Instead, you can load ID from file using 'idfile' argument. + +Generating ID: + + > wnode -generatekey + +result: + + c74ea2702eb32f523acb118649998e1c8b5690cf0a14bffda7e87b411db3499a + +Then save it to file: + + > echo c74ea2702eb32f523acb118649998e1c8b5690cf0a14bffda7e87b411db3499a > pk1.txt + +Then start the bootstrap node with persistent ID: + + > wnode -forwarder -standalone -ip=127.0.0.1:30379 -idfile=pk1.txt + +result: + + my public key: 0x04be81a00a90f5c21ead8887eaa254b3f7a37e06f8f2d776dcc46954a228bc50c6fb6dfd155f7e44e6fef9b62fdf6dad041759b864d2cbe4089b6f5c16a817ff46 enode://7d13360f5b1ddcf6947f244639113597a863abba0589d2fa5fffb2816ead0acea6211d5778a8be648e45e81ed881f4c1f5c9bbbf0e79065dfb54bcd97de3beab@127.0.0.1:30379 + Filter is configured for the topic: 5a4ea131 + Bootstrap Whisper node started + +Now you can always use the same command to connect to your bootstrap node: + + > wnode -test -boot=enode://7d13360f5b1ddcf6947f244639113597a863abba0589d2fa5fffb2816ead0acea6211d5778a8be648e45e81ed881f4c1f5c9bbbf0e79065dfb54bcd97de3beab@127.0.0.1:30379 + +Please note that ID file is stored unencrypted. It should be used only for test purposes. + +Of course, two local whisper nodes are only useful for the most basic tests. +In order to set up a bootstrap node on a server with dedicated IP address, you need to specify its IP explicitly: + + > wnode -forwarder -standalone -ip=52.178.211.103:30379 + +#### Chat + +Now we will start a chat between two or more nodes sharing the same password, using symmetric encryption. One of the nodes should be started with 'standalone' flag, and another must connect to the first one. It is easy to do on the same machine or on a dedicated server. But what if two peers are behind distinct NAT? In that case, you need a third bootstrap node on a dedicated server, which both peers can connect to. At the time of writing we have out test node with the following enode: +enode://d25474361659861e9e651bc728a17e807a3359ca0d344afd544ed0f11a31faecaf4d74b55db53c6670fd624f08d5c79adfc8da5dd4a11b9213db49a3b750845e@52.178.209.125:30379, +to which both peers can connect with the following command: + + > wnode -boot=enode://d25474361659861e9e651bc728a17e807a3359ca0d344afd544ed0f11a31faecaf4d74b55db53c6670fd624f08d5c79adfc8da5dd4a11b9213db49a3b750845e@52.178.209.125:30379 + +Then you will be prompted to enter the password for symmetric encryption. From this password symmetric key will be derived. The topic will be derived from the password as well, unless you provide your own (which is strongly encouraged for any meaningful communication): + + > wnode -topic=a6fcb30d -boot=enode://d25474361659861e9e651bc728a17e807a3359ca0d344afd544ed0f11a31faecaf4d74b55db53c6670fd624f08d5c79adfc8da5dd4a11b9213db49a3b750845e@52.178.209.125:30379 + +Now you can type text messages: + + hello world! + + 1493061848 <031792461900245c6919c4b23447ef8ba43f79a2>: hello world! + +You will see your own message successfully decrypted and printed on the screen. The first number (1493061848) is UNIX time in seconds. This format is useful for Mail Client/Server tests. The number in brackets is ID with which the message is signed. In this case -- your own ID. If you see only zeros there, it means the message is not signed, although encrypted with the right key. Another wnode peer will show the same output: + + 1493061848 [031792461900245c6919c4b23447ef8ba43f79a2]: hello world! + +Almost the same, only the brackets are different, indicating that this is not its own message -- originated from somebody else. + +#### Chat with Asymmetric Encryption + +Connect both peers to the same bootstrap node again, but this time with 'asym' flag: + + > wnode -topic=a6fcb30d -asym -boot=enode://d25474361659861e9e651bc728a17e807a3359ca0d344afd544ed0f11a31faecaf4d74b55db53c6670fd624f08d5c79adfc8da5dd4a11b9213db49a3b750845e@52.178.209.125:30379 + +result: + + my public key: 0x0405007821171295a716c9d091371e836e98a5206d5b9ce9177df90c83fc308ebae2786a9c7bff999ad83d12be08e597d4b5a5240f3bb0bc366f008b7d0908df8a + enode://efe233263c78482111ba6c058ccc69b7a2ea3372774733def4fd5a357dfbaa67657e665078d573f11876fd2b7d75d41926976f41e257f91b486e9d36f4143c8a@[::]:42562 + Whisper node started + Connected to peer. + Please enter the peer's public key: + +First line of the output contains the key which should be passed to anther peer, and vice versa. Then you can proceed with the chat as in the previous case. + +#### Sending and receiving files + +Start wnode with 'fileexchange' flag, and 'test' flag for simplicity. Suppose we want to store the incoming messages in the directory /home/tester/tmp/msg. In that case: + + > wnode -standalone -ip=127.0.0.1:30379 -idfile=pk1.txt -fileexchange -savedir=/home/tester/tmp/msg + +Now, start another wnode and connect to the first one: + + > wnode -test -boot=enode://7d13360f5b1ddcf6947f244639113597a863abba0589d2fa5fffb2816ead0acea6211d5778a8be648e45e81ed881f4c1f5c9bbbf0e79065dfb54bcd97de3beab@127.0.0.1:30379 + +After you will type and send messages from the second node, you will see the first one to display something like this: + + 1493124416 {624fdf6983940c7ffa8a4742f76dc78ae9775c47}: message received and saved as 'aa6f339e830c86718ddf4254038dd9fa8da6494e3f3c856af500a5aeaf0df62d' (4 bytes) + +As you see, messages are not displayed, but saved instead. Now you can open the file /home/tester/tmp/msg/aa6f339e830c86718ddf4254038dd9fa8da6494e3f3c856af500a5aeaf0df62d and examine its contents. + +If you want to send a file from the 'fileexchange' peer, just type the file name. For example: + + > /home/tester/tmp/msg/aa6f339e830c86718ddf4254038dd9fa8da6494e3f3c856af500a5aeaf0df62d + +Another peer should receive the message, decrypt and display it on the screen. +If you want to use your own password instead of hardcoded one, just call wnode without 'test' flag. +Of course, you can also switch to asymmetric encryption by providing 'asym' flag. + +#### Mail Server & Client + +Whisper protocol allows you to exchange messages with other peers only if you are online. But what if you go offline? Will important messages be lost forever? The golang implementation of Whisper v5 has a built-in support for Mail Client/Server functionality, which allows to create very secure (and even dark) anonymous email-like system. Wnode is designed to demonstrate the viability of such project. + +Mail Server and Client must have direct connection, since they exchange special kind of messages, which are not propagated any further. The reason for that is simple: if you receive the old (expired) message from the Server, and try to send it to other peers, they will recognise the message as expired, and drop connection with you. + +Starting Mail Server: + + > wnode -mailserver -forwarder -standalone -test -ip=127.0.0.1:30381 -idfile=pk1.txt -dbpath=/home/tester/tmp/arj + +Now start another node, connect to the Server, and send some test messages to fill the database: + + > wnode -test -boot=enode://7d13360f5b1ddcf6947f244639113597a863abba0589d2fa5fffb2816ead0acea6211d5778a8be648e45e81ed881f4c1f5c9bbbf0e79065dfb54bcd97de3beab@127.0.0.1:30381 + +Note the UNIX time of the messages. For example: 1493127055. +Now start the Mail Client and connect to the Server: + + > wnode -mailclient -test -boot=enode://7d13360f5b1ddcf6947f244639113597a863abba0589d2fa5fffb2816ead0acea6211d5778a8be648e45e81ed881f4c1f5c9bbbf0e79065dfb54bcd97de3beab@127.0.0.1:30381 + +You will be prompted to enter the time range of the archived messages you want to receive: + + > Please enter the lower limit of the time range (unix timestamp): 1493127000 + > Please enter the upper limit of the time range (unix timestamp): 1493127099 + > Please enter the topic (hexadecimal): + +You can leave the topic empty for now, in which case all the messages will be delivered, regardless of the topic. +The message should be delivered by the the Server, decrypted by the Client and displayed on the screen. diff --git a/docs/Disclaimer.md b/docs/Disclaimer.md new file mode 100644 index 0000000000..7b0c48512d --- /dev/null +++ b/docs/Disclaimer.md @@ -0,0 +1,84 @@ +# Disclaimer + +Safety caveats + +## Security warnings + +* **You are responsible for your own computer security.** If your machine is compromised you **will** lose your ether, access to any contracts and maybe more. + +* **You are responsible for your own actions.** If you mess something up or break any laws while using this software, it's your fault, and your fault only. + +* **You are responsible for your own karma.** Don't be a jerk and respect others. + +* This software is open source under a [GNU Lesser General Public License](https://www.gnu.org/licenses/lgpl-3.0.en.html) license. + +## Legal warning: Disclaimer of Liabilites and Warranties + +### Short version + +* **The user expressly knows and agrees that the user is using the ethereum platform at the user’s sole risk.** +* **The user represents that the user has an adequate understanding of the risks, usage and intricacies of cryptographic tokens and blockchain-based open source software, eth platform and eth.** +* **The user acknowledges and agrees that, to the fullest extent permitted by any applicable law, the disclaimers of liability contained herein apply to any and all damages or injury whatsoever caused by or related to risks of, use of, or inability to use, eth or the ethereum platform under any cause or action whatsoever of any kind in any jurisdiction, including, without limitation, actions for breach of warranty, breach of contract or tort (including negligence) and that neither stiftung ethereum nor the ethereum team shall be liable for any indirect, incidental, special, exemplary or consequential damages, including for loss of profits, goodwill or data.** +* **Some jurisdictions do not allow the exclusion of certain warranties or the limitation or exclusion of liability for certain types of damages. therefore, some of the above limitations in this section may not apply to a user. In particular, nothing in these terms shall affect the statutory rights of any user or exclude injury arising from any willful misconduct or fraud of stiftung ethereum.** + +### Long Version: Terms and Conditions + +The following Terms and Conditions (“Terms”) govern the use of the Ethereum open source software platform (“Ethereum Platform”). Prior to any use of the Ethereum Platform, the User confirms to understand and expressly agrees to all of the Terms. All capitalized terms in this agreement will be given the same effect and meaning as in the Terms. The group of developers and other personnel that is now, or will be, employed by, or contracted with, Stiftung Ethereum (“Stiftung Ethereum”) is termed the “Ethereum Team.” The Platform will be developed by persons and entities who support Ethereum, including both volunteers and developers who are paid by nonprofit entities interested in supporting the Ethereum Platform. + +The user acknowledges the following serious risks to any use the Ethereum Platform and ETH and expressly agrees not to hold liable Ethereum Stiftung or Ethereum Team should any of these risks occur: + +#### Risk of Regulatory Actions in One or More Jurisdictions + +The Ethereum Platform and ETH could be impacted by one or more regulatory inquiries or regulatory action, which could impede or limit the ability of Stiftung Ethereum to continue to develop the Ethereum Platform, or which could impeded or limit the ability of User to use Ethereum Platform or ETH. + +#### Risk of Alternative, Unofficial Ethereum Networks + +It is possible that alternative Ethereum-based networks could be established, which utilize the same open source source code and open source protocol underlying the Ethereum Platform. The Ethereum network may compete with these alternative Ethereum-based networks, which could potentially negatively impact the Ethereum Platform and ETH. + +#### Risk of Insufficient Interest in the Ethereum Platform or Distributed Applications + +It is possible that the Ethereum Platform will not be used by a large number of external businesses, individuals, and other organizations and that there will be limited public interest in the creation and development of distributed applications. Such a lack of interest could impact the development of the Ethereum Platform and potential uses of ETH. It cannot predict the success of its own development efforts or the efforts of other third parties. + +#### Risk that the Ethereum Platform, As Developed, Will Not Meet the Expectations of User + +The User recognizes that the Ethereum Platform is under development and may undergo significant changes before release. User acknowledges that any expectations regarding the form and functionality of the Ethereum Platform held by the User may not be met upon release of the Ethereum Platform, for any number of reasons including a change in the design and implementation plans and execution of the implementation of the Ethereum Platform. + +#### Risk of Security Weaknesses in the Ethereum Platform Core Infrastructure Software + +The Ethereum Platform rests on open-source software, and there is a risk that the Ethereum Stiftung or the Ethereum Team, or other third parties not directly affiliated with the Stiftung Ethereum, may introduce weaknesses or bugs into the core infrastructural elements of the Ethereum Platform causing the system to lose ETH stored in one or more User accounts or other accounts or lose sums of other valued tokens issued on the Ethereum Platform. + +#### Risk of Weaknesses or Exploitable Breakthroughs in the Field of Cryptography + +Cryptography is an art, not a science. And the state of the art can advance over time Advances in code cracking, or technical advances such as the development of quantum computers, could present risks to cryptocurrencies and the Ethereum Platform, which could result in the theft or loss of ETH. To the extent possible, Stiftung Ethereum intends to update the protocol underlying the Ethereum Platform to account for any advances in cryptography and to incorporate additional security measures, but cannot it cannot predict the future of cryptography or the success of any future security updates. + +#### Risk of Ether Mining Attacks + +As with other cryptocurrencies, the blockchain used for the Ethereum Platform is susceptible to mining attacks, including but not limited to double-spend attacks, majority mining power attacks, “selfish-mining” attacks, and race condition attacks. Any successful attacks present a risk to the Ethereum Platform, expected proper execution and sequencing of ETH transactions, and expected proper execution and sequencing of contract computations. Despite the efforts of the Ethereum Stiftung and Team, known or novel mining attacks may be successful. + +#### Risk of Rapid Adoption and Increased Demand + +If the Ethereum Platform is rapidly adopted, the demand for ETH could rise dramatically and at a pace that exceeds the rate with which ETH miners can create new ETH tokens. Under such a scenario, the entire Ethereum Platform could become destabilized, due to the increased cost of running distributed applications. In turn, this could dampen interest in the Ethereum Platform and ETH. Instability in the demand of for ETH may lead to a negative change of the economical parameters of an Ethereum based business which could result in the business being unable to continue to operate economically or to cease operation. + +#### Risk of Rapid Adoption and Insufficiency of Computational Application Processing Power on the Ethereum Platform + +If the Ethereum Platform is rapidly adopted, the demand for transaction processing and distributed application computations could rise dramatically and at a pace that exceeds the rate with which ETH miners can bring online additional mining power. Under such a scenario, the entire Ethereum Platform could become destabilized, due to the increased cost of running distributed applications. In turn, this could dampen interest in the Ethereum Platform and ETH. Insufficiency of computational resources and an associated rise in the price of ETH could result in businesses being unable to acquire scarce computational resources to run their distributed applications. This would represent revenue losses to businesses or worst case, cause businesses to cease operations because such operations have become uneconomical due to distortions in the crypto-economy. + +Acknowledgment, Acceptance of all Risks and Disclaimer of Warranties and Liabilities +**THE USER EXPRESSLY KNOWS AND AGREES THAT THE USER IS USING THE ETHEREUM PLATFORM AT THE USER’S SOLE RISK. THE USER REPRESENTS THAT THE USER HAS AN ADEQUATE UNDERSTANDING OF THE RISKS, USAGE AND INTRICACIES OF CRYPTOGRAPHIC TOKENS AND BLOCKCHAIN-BASED OPEN SOURCE SOFTWARE, ETH PLATFORM AND ETH. THE USER ACKNOWLEDGES AND AGREES THAT, TO THE FULLEST EXTENT PERMITTED BY ANY APPLICABLE LAW, THE DISCLAIMERS OF LIABILITY CONTAINED HEREIN APPLY TO ANY AND ALL DAMAGES OR INJURY WHATSOEVER CAUSED BY OR RELATED TO RISKS OF, USE OF, OR INABILITY TO USE, ETH OR THE ETHEREUM PLATFORM UNDER ANY CAUSE OR ACTION WHATSOEVER OF ANY KIND IN ANY JURISDICTION, INCLUDING, WITHOUT LIMITATION, ACTIONS FOR BREACH OF WARRANTY, BREACH OF CONTRACT OR TORT (INCLUDING NEGLIGENCE) AND THAT NEITHER STIFTUNG ETHEREUM NOR ETHERUM TEAM SHALL BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES, INCLUDING FOR LOSS OF PROFITS, GOODWILL OR DATA. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF CERTAIN WARRANTIES OR THE LIMITATION OR EXCLUSION OF LIABILITY FOR CERTAIN TYPES OF DAMAGES. THEREFORE, SOME OF THE ABOVE LIMITATIONS IN THIS SECTION MAY NOT APPLY TO A USER. IN PARTICULAR, NOTHING IN THESE TERMS SHALL AFFECT THE STATUTORY RIGHTS OF ANY USER OR EXCLUDE INJURY ARISING FROM ANY WILLFUL MISCONDUCT OR FRAUD OF STIFTUNG ETHEREUM**. + +#### Dispute Resolution + +All disputes or claims arising out of, relating to, or in connection with the Terms, the breach thereof, or use of the Ethereum Platform shall be finally settled under the Rules of Arbitration of the International Chamber of Commerce by one or more arbitrators appointed in accordance with said Rules. All claims between the parties relating to these Terms that are capable of being resolved by arbitration, whether sounding in contract, tort, or otherwise, shall be submitted to ICC arbitration. Prior to commencing arbitration, the parties have a duty to negotiate in good faith and attempt to resolve their dispute in a manner other than by submission to ICC arbitration. The arbitration panel shall consist of one arbitrator only, unless the ICC Court of Arbitration determines that the dispute is such as to warrant three arbitrators. If the Court determines that one arbitrator is sufficient, then such arbitrator shall be Swiss resident. If the Court determines that three arbitrators are necessary, then each party shall have 30 days to nominate an arbitrator of its choice -- in the case of the Claimant, measured from receipt of notification of the ICC Court’s decision to have three arbitrators; in the case of Respondent, measured from receipt of notification of Claimant’s nomination. All nominations must be Swiss resident. If a party fails to nominate an arbitrator, the Court will do so. The Court shall also appoint the chairman. All arbitrators shall be and remain “independent” of the parties involved in the arbitration. The place of arbitration shall be Zug, Switzerland. The language of the arbitration shall be English. In deciding the merits of the dispute, the tribunal shall apply the laws of Switzerland and any discovery shall be limited and shall not involve any depositions or any other examinations outside of a formal hearing. The tribunal shall not assume the powers of amiable compositeur or decide the case ex aequo et bono. In the final award, the tribunal shall fix the costs of the arbitration and decide which of the parties shall bear such costs in what proportion. Every award shall be binding on the parties. The parties undertake to carry out the award without delay and waive their right to any form of recourse against the award in so far as such waiver can validly be made. + +#### Force Majeure + +**STIFTUNG ETHEREUM** is finally not liable for: + +* unavoidable casualty, +* delays in delivery of materials, +* embargoes, +* government orders, +* acts of civil or military authorities, +* lack of energy, or +* any similar unforeseen event that renders performance commercially implausible. + \ No newline at end of file diff --git a/docs/Ethereum-Specification.md b/docs/Ethereum-Specification.md new file mode 100644 index 0000000000..b1c857b856 --- /dev/null +++ b/docs/Ethereum-Specification.md @@ -0,0 +1,28 @@ +Specifications of all ethereum technologies, languages, protocols, etc. + +### Whitepapers and design rationale + +- [Ethereum Whitepaper](https://github.com/ethereum/wiki/wiki/White-Paper) +- [Design Rationale](https://github.com/ethereum/wiki/wiki/Design-Rationale) +- [Ethereum Yellow Paper](http://gavwood.com/Paper.pdf) +- [ÐΞVp2p Whitepaper](https://github.com/ethereum/wiki/wiki/libp2p-Whitepaper) (WiP) +- [Ethash](https://github.com/ethereum/wiki/wiki/Ethash) + +### Specs + +- [JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API#a) +- [Generic JSON RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) +- [JSRE admin API](https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console#console-api) +- [RLP](https://github.com/ethereum/wiki/wiki/RLP) +- [ÐΞVp2p Wire Protocol](https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol) +- [Web3 Secret Storage](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) +- [Patricia Tree](https://github.com/ethereum/wiki/wiki/Patricia-Tree) +- [Wire protocol](https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol) +- [Light client protocol](https://github.com/ethereum/wiki/wiki/Light-client-protocol) +- [Solidity, Docs & ABI](https://github.com/ethereum/wiki/wiki/Solidity,-Docs-and-ABI) +- [NatSpec](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format) +- [Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) +- [Ethash](https://github.com/ethereum/wiki/wiki/Ethash) +- [Ethash C API](https://github.com/ethereum/wiki/wiki/Ethash-C-API) +- [Ethash DAG](https://github.com/ethereum/wiki/wiki/Ethash-DAG) +- [ICAP: Inter-exchange Client Address Protocol](https://github.com/ethereum/wiki/wiki/ICAP:-Inter-exchange-Client-Address-Protocol) diff --git a/docs/Ethereum-on-Android.md b/docs/Ethereum-on-Android.md new file mode 100644 index 0000000000..7dd9d9ab58 --- /dev/null +++ b/docs/Ethereum-on-Android.md @@ -0,0 +1,63 @@ +Building Geth for Android is a non trivial task, as it requires cross compiling external C dependencies ([GNU Arithmetic Library](https://gmplib.org/)); internal C dependencies ([ethash](https://github.com/ethereum/ethash)); as well as the entire CGO enabled Go code-base to Android. This is further complicated by the Position Independent Executables (PIE) security feature introduced since Android 4.1 Jelly Bean, requiring different compiler and linker options based on the target Android platform version. + +To cope with all the build issues, the [`xgo`](https://github.com/karalabe/xgo) CGO enabled Go cross compiler is used, which assembles an entire multi-platform cross compiler suite into a single mega docker container. Details about using `xgo` can be found in the project's [README](https://github.com/karalabe/xgo/blob/master/README.md), with Ethereum specifics on the go-ethereum cross compilation [wiki page](https://github.com/ethereum/go-ethereum/wiki/Cross-compiling-Ethereum). + +TL;DR + +``` +$ go get -u github.com/karalabe/xgo +$ xgo --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 \ + --branch=develop \ + --targets=android-16/arm \ + github.com/ethereum/go-ethereum/cmd/geth + +$ ls -al + -rwxr-xr-x 1 root root 23213348 Sep 14 19:35 geth-android-16-arm +``` + +## Deploying a binary + +Currently `xgo` will compile a native Android binary that can be copied onto a device and executed from a terminal emulator. As Ethereum Android support at the moment is mostly a developer feature, there have been no attempts at making it even remotely user friendly (installers, APKs, etc). + +To push a native binary onto an Android device, you'll need an Android SDK installed. The most lightweight solution is the standalone [SDK Tools Only](https://developer.android.com/sdk/index.html#Other) package. Download and extract for your local machine's platform. Since building the binary is already done, we only need the [Android Debug Bridge](http://developer.android.com/tools/help/adb.html) to push it to our device, which can be installed using the SDK's `android` tool `$YOUR_SDK_PATH/tools/android` -> `Android SDK Platform Tools` (deselect everything else). We'll assume `$YOUR_SDK_PATH/platform-tools/adb` is in the PATH environmental variable from now on. + +You can list the available devices via: + +``` +$ adb devices +List of devices attached +0149CBF30201400E device +``` + +Deploying the binary to an Android device can be done in two steps. First copy the binary into the non-executable `sdcard` filesystem on the device. You may be asked the first time by the device to grant developer permission (also developer mode should be enabled on the devices prior). + +``` +$ adb push $PATH_TO_BINARY/geth-android-16-arm /sdcard/ +1984 KB/s (23213348 bytes in 11.421s) +``` + +Then the binary needs to be moved to a file system with executable permissions, and said permissions need to be granted. On an unrooted phone the following path should be accessible with USB developer options. + +``` +$ adb shell +$ cp /sdcard/geth-android-16-arm /data/local/tmp/geth +$ cd /data/local/tmp +$ chmod 751 geth +``` + +## Running the deployed binary + +After pushing the binary to the device and setting the appropriate permissions, you may execute Geth straight from the Android Debug Bridge shell: + +``` +$ ./geth +I0911 11:09:05.329120 1427 cmd.go:125] Starting Geth/v1.1.0/android/go1.5.1 +I0911 11:09:05.466782 1427 server.go:311] Starting Server +I0911 11:09:05.823965 1427 udp.go:207] Listening, enode://824e1a16bd6cb9931bec1ab6268cd76571936d5674505d53c7409b2b860cd9e396a66c7fe4c3ad4e60c43fe42408920e33aaf3e7bbdb6123f8094dbc423c2bb1@[::]:30303 +I0911 11:09:05.832037 1427 backend.go:560] Server started +I0911 11:09:05.848936 1427 server.go:552] Listening on [::]:30303 +``` + +A fancier way would be to start a terminal emulator on the Android device itself and run the binary expressly from it (remember, deployed at `/data/local/tmp/geth`): + +![Geth on Android](http://i.imgur.com/wylOsBL.jpg) \ No newline at end of file diff --git a/docs/FAQ.md b/docs/FAQ.md new file mode 100644 index 0000000000..425e0f2ac7 --- /dev/null +++ b/docs/FAQ.md @@ -0,0 +1,46 @@ +*** +**Q.** I noticed my peercount slowly decrease, and now it is at 0. Restarting doesn't get any peers. + +**A.** Check and sync your clock with ntp. [Example](http://askubuntu.com/questions/254826/how-to-force-a-clock-update-using-ntp) `sudo ntpdate -s time.nist.gov` + +*** + +**Q.** I would like to run multiple geth instances but got the error "Fatal: blockchain db err: resource temporarily unavailable". + +**A.** Geth uses a datadir to store the blockchain, accounts and some additional information. This directory cannot be shared between running instances. If you would like to run multiple instances follow [these](https://github.com/ethereum/go-ethereum/wiki/Setting-up-private-network-or-local-cluster) instructions. + +**Q.** How do Ethereum syncing work? + +**A.** The current default mode of sync for Geth is called fast sync. Instead of starting from the genesis block and reprocessing all the transactions that ever occurred (which could take weeks), fast sync downloads the blocks, and only verifies the associated proof-of-works. Downloading all the blocks is a straightforward and fast procedure and will relatively quickly reassemble the entire chain. + +Many people falsely assume that because they have the blocks, they are in sync. Unfortunately this is not the case, since no transaction was executed, so we do not have any account state available (ie. balances, nonces, smart contract code and data). These need to be downloaded separately and cross checked with the latest blocks. This phase is called the state trie download and it actually runs concurrently with the block downloads; alas it take a lot longer nowadays than downloading the blocks. + +So, what's the state trie? In the Ethereum mainnet, there are a ton of accounts already, which track the balance, nonce, etc of each user/contract. The accounts themselves are however insufficient to run a node, they need to be cryptographically linked to each block so that nodes can actually verify that the account's are not tampered with. This cryptographic linking is done by creating a tree data structure above the accounts, each level aggregating the layer below it into an ever smaller layer, until you reach the single root. This gigantic data structure containing all the accounts and the intermediate cryptographic proofs is called the state trie. + +Ok, so why does this pose a problem? This trie data structure is an intricate interlink of hundreds of millions of tiny cryptographic proofs (trie nodes). To truly have a synchronized node, you need to download all the account data, as well as all the tiny cryptographic proofs to verify that noone in the network is trying to cheat you. This itself is already a crazy number of data items. The part where it gets even messier is that this data is constantly morphing: at every block (15s), about 1000 nodes are deleted from this trie and about 2000 new ones are added. This means your node needs to synchronize a dataset that is changing 200 times per second. The worst part is that while you are synchronizing, the network is moving forward, and state that you begun to download might disappear while you're downloading, so your node needs to constantly follow the network while trying to gather all the recent data. But until you actually do gather all the data, your local node is not usable since it cannot cryptographically prove anything about any accounts. + +If you see that you are 64 blocks behind mainnet, you aren't yet synchronized, not even close. You are just done with the block download phase and still running the state downloads. You can see this yourself via the seemingly endless Imported state entries [...] stream of logs. You'll need to wait that out too before your node comes truly online. + +**Q: The node just hangs on importing state enties?!** + +**A**: The node doesn't hang, it just doesn't know how large the state trie is in advance so it keeps on going and going and going until it discovers and downloads the entire thing. + +The reason is that a block in Ethereum only contains the state root, a single hash of the root node. When the node begins synchronizing, it knows about exactly 1 node and tries to download it. That node, can refer up to 16 new nodes, so in the next step, we'll know about 16 new nodes and try to download those. As we go along the download, most of the nodes will reference new ones that we didn't know about until then. This is why you might be tempted to think it's stuck on the same numbers. It is not, rather it's discovering and downloading the trie as it goes along. + +**Q: I'm stuck at 64 blocks behind mainnet?!** + +*A:* As explained above, you are not stuck, just finished with the block download phase, waiting for the state download phase to complete too. This latter phase nowadays take a lot longer than just getting the blocks. + +**Q: Why does downloading the state take so long, I have good bandwidth?** + +**A:** State sync is mostly limited by disk IO, not bandwidth. + +The state trie in Ethereum contains hundreds of millions of nodes, most of which take the form of a single hash referencing up to 16 other hashes. This is a horrible way to store data on a disk, because there's almost no structure in it, just random numbers referencing even more random numbers. This makes any underlying database weep, as it cannot optimize storing and looking up the data in any meaningful way. + +Not only is storing the data very suboptimal, but due to the 200 modification / second and pruning of past data, we cannot even download it is a properly pre-processed way to make it import faster without the underlying database shuffling it around too much. The end result is that even a fast sync nowadays incurs a huge disk IO cost, which is too much for a mechanical hard drive. + +**Q: Wait, so I can't run a full node on an HDD?** + +**A:** Unfortunately not. Doing a fast sync on an HDD will take more time than you're willing to wait with the current data schema. Even if you do wait it out, an HDD will not be able to keep up with the read/write requirements of transaction processing on mainnet. + +You however should be able to run a light client on an HDD with minimal impact on system resources. If you wish to run a full node however, an SSD is your only option. \ No newline at end of file diff --git a/docs/Gas-Price-Oracle.md b/docs/Gas-Price-Oracle.md new file mode 100644 index 0000000000..2aaa7ac055 --- /dev/null +++ b/docs/Gas-Price-Oracle.md @@ -0,0 +1,19 @@ +The gas price oracle is a helper function of the Geth client that tries to find an appropriate default gas price when sending transactions. It can be parametrized with the following command line options: + +- gpomin: lower limit of suggested gas price. This should be set at least as high as the "gasprice" setting usually used by miners so that your transactions will not be rejected automatically because of a too low price. + +- gpomax: higher limit of suggested gas price. During load peaks when there is a competition between transactions to get into the blocks, the price needs to be limited, otherwise the oracle would eventually try to overbid everyone else at any price. + +- gpofull: a block is considered "full" when a certain percentage of the block gas limit (specified in percents) is used up by transactions. If a block is not "full", that means that a transaction could have been accepted even with a minimal price offered. + +- gpobasedown: an exponential ratio (specified in 1/1000ths) by which the base price decreases when the lowest acceptable price of the last block is below the last base price. + +- gpobaseup: an exponential ratio (specified in 1/1000ths) by which the base price increases when the lowest acceptable price of the last block is over the last base price. + +- gpobasecf: a correction factor (specified in percents) of the base price. The suggested price is the corrected base price, limited by gpomin and gpomax. + +The lowest acceptable price is defined as a price that could have been enough to insert a transaction into a certain block. Although this value varies slightly with the gas used by the particular transaction, it is aproximated as follows: if the block is full, it is the lowest transaction gas price found in that block. If the block is not full, it equals to gpomin. + +The base price is a moving value that is adjusted from block to block, up if it was lower than the lowest acceptable price, down otherwise. Note that there is a slight amount of randomness added to the correction factors so that your client will not behave absolutely predictable on the market. + +If you want to specify a constant for the default gas price and not use the oracle, set both gpomin and gpomax to the same value. \ No newline at end of file diff --git a/docs/Geth.md b/docs/Geth.md new file mode 100644 index 0000000000..56e40d5b6d --- /dev/null +++ b/docs/Geth.md @@ -0,0 +1,108 @@ +`geth` is the the command line interface for running a full ethereum node implemented in Go. +It is the main deliverable of the [Frontier Release](https://github.com/ethereum/go-ethereum/wiki/Frontier) + +## Capabilities + +By installing and running `geth`, you can take part in the ethereum frontier live network and +* mine real ether +* transfer funds between addresses +* create contracts and send transactions +* explore block history +* and much much more + +## Install + +Supported Platforms are Linux, Mac Os and Windows. + +We support two types of installation: binary or scripted install for users. +See [Install instructions](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum) for binary and scripted installs. + +Developers and community enthusiast are advised to read the [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers%27-Guide), which contains detailed instructions for manual build from source (on any platform) as well as detailed tips on testing, monitoring, contributing, debugging and submitting pull requests on github. + +## Interfaces + +* Javascript Console: `geth` can be launched with an interactive console, that provides a javascript runtime environment exposing a javascript API to interact with your node. [Javascript Console API](https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console) includes the `web3` javascript Ðapp API as well as an additional admin API. +* JSON-RPC server: `geth` can be launched with a json-rpc server that exposes the [JSON-RPC API](https://github.com/ethereum/wiki/wiki/JSON-RPC) +* [Command line options](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options) documents command line parameters as well as subcommands. + +## Basic Use Case Documentation + +* [Managing accounts](https://github.com/ethereum/go-ethereum/wiki/Managing-your-accounts) +* [Mining](https://github.com/ethereum/go-ethereum/wiki/mining) + +**Note** buying and selling ether through exchanges is not discussed here. + +## License + +The Ethereum Core Protocol licensed under the [GNU Lesser General Public License](https://www.gnu.org/licenses/lgpl.html). All frontend client software (under [cmd](https://github.com/ethereum/go-ethereum/tree/develop/cmd)) is licensed under the [GNU General Public License](https://www.gnu.org/copyleft/gpl.html). + +## Reporting + +Security issues are best sent to security@ethereum.org or shared in PM with devs on one of the channels (see Community and Suppport). + +Non-sensitive bug reports are welcome on github. Please always state the version (on master) or commit of your build (if on develop), give as much detail as possible about the situation and the anomaly that occurred. Provide logs or stacktrace if you can. + +## Contributors + +Ethereum is joint work of ETHDEV and the community. + +Name or blame = list of contributors: +* [go-ethereum](https://github.com/ethereum/go-ethereum/graphs/contributors) +* [cpp-ethereum](https://github.com/ethereum/cpp-ethereum/graphs/contributors) +* [web3.js](https://github.com/ethereum/web3.js/graphs/contributors) +* [ethash](https://github.com/ethereum/ethash/graphs/contributors) +* [netstats](https://github.com/cubedro/eth-netstats/graphs/contributors), +[netintelligence-api](https://github.com/cubedro/eth-net-intelligence-api/graphs/contributors) + +## Community and support + +### Ethereum on social media + +- Main site: https://www.ethereum.org +- Forum: https://forum.ethereum.org +- Github: https://github.com/ethereum +- Blog: https://blog.ethereum.org +- Wiki: http://wiki.ethereum.org +- Twitter: http://twitter.com/ethereumproject +- Reddit: http://reddit.com/r/ethereum +- Meetups: http://ethereum.meetup.com +- Facebook: https://www.facebook.com/ethereumproject +- Youtube: http://www.youtube.com/ethereumproject +- Google+: http://google.com/+EthereumOrgOfficial + +### IRC + +IRC Freenode channels: +* `#ethereum`: for general discussion +* `#ethereum-dev`: for development specific questions and discussions +* `##ethereum`: for offtopic and banter +* `#ethereumjs`: for questions related to web3.js and node-ethereum +* `#ethereum-markets`: Trading +* `#ethereum-mining` Mining +* `#dappdevs`: Dapp developers channel +* `#ethdev`: buildserver etc + +[IRC Logs by ZeroGox](https://zerogox.com/bot/log) + +### Gitter + +* [go-ethereum Gitter](https://gitter.im/ethereum/go-ethereum) +* [cpp-ethereum Gitter](https://gitter.im/ethereum/cpp-ethereum) +* [web3.js Gitter](https://gitter.im/ethereum/web3.js) +* [ethereum documentation project Gitter](https://gitter.im/ethereum/frontier-guide) + +### Forum + +- [Forum](https://forum.ethereum.org/categories/go-implementation) + +### The ZeroGox Bot + +[ZeroGox Bot](https://zerogox.com/bot) + +### Dapp developers' mailing list + +https://dapplist.net/ + +### Helpdesk + +On gitter, irc, skype or mail to helpdesk@ethereum.org diff --git a/docs/Go-ethereum-management-API's.md b/docs/Go-ethereum-management-API's.md new file mode 100644 index 0000000000..f2289c9004 --- /dev/null +++ b/docs/Go-ethereum-management-API's.md @@ -0,0 +1 @@ +Moved: [Management APIs](https://github.com/ethereum/go-ethereum/wiki/Management-APIs) \ No newline at end of file diff --git a/docs/How-to-Whisper.md b/docs/How-to-Whisper.md new file mode 100644 index 0000000000..f5d5c123f4 --- /dev/null +++ b/docs/How-to-Whisper.md @@ -0,0 +1,97 @@ +Whisper is a pure identity-based messaging system. Whisper provides a low-level (non-application-specific) but easily-accessible API without being based upon or prejudiced by the low-level hardware attributes and characteristics, particularly the notion of singular endpoints. + +This tutorial assumes you've read [p2p 101](https://github.com/ethereum/go-ethereum/wiki/Peer-to-Peer). If you haven't read it I suggest you read it. This tutorial will guide you to setting up a full p2p server with whisper capabilities. + +Let's quickly cover some of whisper's basic functionality and discuss it in greater detail later. + +```go +whisper.Send(myEnvelope) +``` + +The notion of envelopes and messages in whisper is somewhat blurred. An application shouldn't ever need to know the difference between the two and should only care about the information it's interested in. Therefor whisper comes with a subscribing mechanism which allows you watch/listen for specific whisper messages (e.g., to you, with a specific topic, etc). + +```go +whisper.Watch(Filter{ + From: myFriendsPubKey, + Fn: func(msg *whisper.Message) { /* ... */ }, +}) +``` + +## Envelopes & Messages + +Whenever you want to send message over the whisper network you need to prove to network you've done some significant work for sealing the message (such is the cost for sending messages) and thus the more work you put in to sealing the message the higher the priority the message will have when propagating it over the network. + +Whisper's *P*roof *o*f *W*ork consists of a simple SHA3 algorithm in which we try to find the smallest number within a given time frame. Giving the algorithm more time will result in a smaller number which means the message has a higher priority in the network. + +Messages are also sealed with a *T*ime *T*o *L*ive. Whisper peers will automatically flush out messages which have exceeded their time to live (with a maximum up to 2 days). + +Additionally messages may also contain a recipient (public key) and a set of topics. Topics will allow us to specify messages their subject (e.g., "shoes", "laptop", "marketplace", "chat"). Topics are automatically hashed and only the first 4 bytes are used during transmission and as such, topics are not 100% reliable, they should be treated as a probabilistic message filter. + +Sending a whisper message requires you to: + +1. create a new `whisper.Message` +2. `Seal` it (optionally encrypt, sign and supply with topics) +3. `Send` it to your peers + +```go +topics := TopicsFromString("my", "message") +msg := whisper.NewMessage([]byte("hello world")) // 1 +envelope := msg.Seal(whisper.Opts{ // 2 + From: myPrivateKey, // Sign it + Topics: topics, +}) +whisper.Send(envelope) // 3 +``` + +Whenever a message needs to be encrypted for a specific recipient supply the `Opts` struct with an additional `To` parameter which accepts the recipients public key (`ecdsa.PublicKey`). + +## Watching & Listening + +Watching for specific messages on the whisper network can be done using the `Watch` method. You have the option to watch for messages from a specific recipient, with specific topics or messages directly directed to you. + +```go +topics := TopicsFromString("my", "message") +whisper.Watch(Filter{ + Topics: topics + Fn: func(msg *Message) { + fmt.Println(msg) + }, +}) +``` + +## Connecting it all together + +Now if we tie it all together and supply whisper as a sub-protocol to the DEV's P2P service we have whisper including peer handling and message propagation. + +```go +package main + +import ( + "fmt" + "log" + "os" + + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/whisper" + "github.com/obscuren/secp256k1-go" +) + +func main() { + pub, _ := secp256k1.GenerateKeyPair() + + whisper := whisper.New() + + srv := p2p.Server{ + MaxPeers: 10, + Identity: p2p.NewSimpleClientIdentity("my-whisper-app", "1.0", "", string(pub)), + ListenAddr: ":8000", + Protocols: []p2p.Protocol{whisper.Protocol()}, + } + if err := srv.Start(); err != nil { + fmt.Println("could not start server:", err) + os.Exit(1) + } + + select {} +} +``` \ No newline at end of file diff --git a/docs/IPFS-&-SWARM.md b/docs/IPFS-&-SWARM.md new file mode 100644 index 0000000000..1afcda2977 --- /dev/null +++ b/docs/IPFS-&-SWARM.md @@ -0,0 +1 @@ +see here https://github.com/ethersphere/go-ethereum/wiki/IPFS-&-SWARM diff --git a/docs/Installation-Instructions-for-ARM.md b/docs/Installation-Instructions-for-ARM.md new file mode 100644 index 0000000000..59a9bc0ce3 --- /dev/null +++ b/docs/Installation-Instructions-for-ARM.md @@ -0,0 +1,11 @@ +# Installation Instructions for ARM + +Geth is built for ARM using cross-compilation. See [Cross compiling Ethereum](https://github.com/ethereum/go-ethereum/wiki/Cross-compiling-Ethereum) for more details. + +## RasPi 2 + +1. Download the precompiled binary from https://geth.ethereum.org/downloads/ +1. Copy it to a location in $PATH (i.e. /usr/local/bin) +1. Run `geth` + +Further details: https://github.com/ethereum/wiki/wiki/Raspberry-Pi-instructions \ No newline at end of file diff --git a/docs/Installation-Instructions-for-Arch.md b/docs/Installation-Instructions-for-Arch.md new file mode 100644 index 0000000000..7524f6a3e3 --- /dev/null +++ b/docs/Installation-Instructions-for-Arch.md @@ -0,0 +1,22 @@ +## Installing using pacman + +The `geth` package is available from the [community repo](https://www.archlinux.org/packages/community/x86_64/geth/). + +You can install it using + +```shell +pacman -S geth +``` + +## Installing from source +Install dependencies +```shell +pacman -S git go gcc +``` + +Download and build geth +```shell +git clone https://github.com/ethereum/go-ethereum +cd go-ethereum +make geth +``` \ No newline at end of file diff --git a/docs/Installation-Instructions-for-FreeBSD.md b/docs/Installation-Instructions-for-FreeBSD.md new file mode 100644 index 0000000000..c0c1e1a841 --- /dev/null +++ b/docs/Installation-Instructions-for-FreeBSD.md @@ -0,0 +1,57 @@ +## Building from source + +### Installing binary package + +Binary packages tend not to be up to date (1.8.9 at the time of writing) with the latest version (1.8.16 at the time of writing). It is recommended that you use ports or compile it yourself. + +```shell +pkg install go-ethereum +``` + +The `geth` command is then available on your system in `/usr/local/bin/geth`, you can start it e.g. on the testnet by typing: + +```shell +geth -rinkeby +``` + +### Using ports + +Go to the `net-p2p/go-ethereum` ports directory: + +```shell +cd /usr/ports/net-p2p/go-ethereum +``` +Then build it the standard way (as root): + +```shell +make install +``` + +### Building Geth (command line client) + +Ports are slightly more up to date (1.8.14 at the time of writing) + +Clone the repository to a directory of your choosing: + +```shell +git clone https://github.com/ethereum/go-ethereum +``` + +Building `geth` requires the Go compiler: + +```shell +pkg install go +``` + +If your golang version is >= 1.5, build the `geth` program using the following command. +```shell +cd go-ethereum +make geth +``` +If your golang version is < 1.5 (quarterly packages, for example), use the following command instead. +```shell +cd go-ethereum +CC=clang make geth +``` + +You can now run `build/bin/geth` to start your node. diff --git a/docs/Installation-Instructions-for-Mac.md b/docs/Installation-Instructions-for-Mac.md new file mode 100644 index 0000000000..92f8ad6c58 --- /dev/null +++ b/docs/Installation-Instructions-for-Mac.md @@ -0,0 +1,55 @@ +## Installing with Homebrew + +By far the easiest way to install go-ethereum is to use our +Homebrew tap. If you don't have Homebrew, [install it first](http://brew.sh). + +Then run the following commands to add the tap and install `geth`: + +```shell +brew tap ethereum/ethereum +brew install ethereum +``` + +You can install the develop branch by running `--devel`: + +```shell +brew install ethereum --devel +``` + +After installing, run `geth account new` to create an account on your node. + +You should now be able to run `geth` and connect to the network. + +Make sure to check the different options and commands with `geth --help` + +For options and patches, see: https://github.com/ethereum/homebrew-ethereum + +## Building from source + +### Building Geth (command line client) + +Clone the repository to a directory of your choosing: + +```shell +git clone https://github.com/ethereum/go-ethereum +``` + +Building `geth` requires the Go compiler: + +```shell +brew install go +``` + +Finally, build the `geth` program using the following command. +```shell +cd go-ethereum +make geth +``` + +If you see some errors related to header files of Mac OS system library, install XCode Command Line Tools, and try again. + +```shell +xcode-select --install +``` + +You can now run `build/bin/geth` to start your node. diff --git a/docs/Installation-Instructions-for-Ubuntu.md b/docs/Installation-Instructions-for-Ubuntu.md new file mode 100644 index 0000000000..80f4125297 --- /dev/null +++ b/docs/Installation-Instructions-for-Ubuntu.md @@ -0,0 +1,45 @@ +## Installing from PPA + +```shell +sudo apt-get install software-properties-common +sudo add-apt-repository -y ppa:ethereum/ethereum +sudo apt-get update +sudo apt-get install ethereum +``` + +If you want to stay on the bleeding edge, install the `ethereum-unstable` package instead. + +After installing, run `geth account new` to create an account on your node. + +You should now be able to run `geth` and connect to the network. + +Make sure to check the different options and commands with `geth --help` + +You can alternatively install only the `geth` CLI with `apt-get install geth` if you don't want to install the other utilities (`bootnode`, `evm`, `disasm`, `rlpdump`, `ethtest`). + +## Building from source + +### Building Geth (command line client) + +Clone the repository to a directory of your choosing: + +```shell +git clone https://github.com/ethereum/go-ethereum +``` +Install latest distribution of Go (v1.7) if you don't have it already: + +[See instructions](https://github.com/ethereum/go-ethereum/wiki/Installing-Go#ubuntu-1404) + +Building `geth` requires Go and C compilers to be installed: + +```shell +sudo apt-get install -y build-essential golang +``` + +Finally, build the `geth` program using the following command. +```shell +cd go-ethereum +make geth +``` + +You can now run `build/bin/geth` to start your node. diff --git a/docs/Installation-instructions-for-Windows.md b/docs/Installation-instructions-for-Windows.md new file mode 100644 index 0000000000..194715f4d0 --- /dev/null +++ b/docs/Installation-instructions-for-Windows.md @@ -0,0 +1,63 @@ +# Binaries + +## Download stable binaries + +All versions of Geth are built and available for download at https://geth.ethereum.org/downloads/. + +The download page provides an installer as well as a zip file. The installer puts geth into your +PATH automatically. The zip file contains the command .exe files and can be used without installing. + +1. Download zip file +1. Extract geth.exe from zip +1. Open a command prompt +1. chdir +1. open geth.exe + +# Source + +## Compiling geth with tools from chocolatey + +The Chocolatey package manager provides an easy way to get +the required build tools installed. If you don't have chocolatey yet, +follow the instructions on https://chocolatey.org to install it first. + +Then open an Administrator command prompt and install the build tools +we need: + +```text +C:\Windows\system32> choco install git +C:\Windows\system32> choco install golang +C:\Windows\system32> choco install mingw +``` + +Installing these packages will set up the `Path` environment variable. +Open a new command prompt to get the new `Path`. The following steps don't +need Administrator privileges. + +Please ensure that the installed Go version is 1.7 (or any later version). + +First we'll create and set up a Go workspace directory layout, +then clone the source. + +***OBS*** If, during the commands below, you get the following message: +``` + WARNING: The data being saved is truncated to 1024 characters. +``` +Then that means that the `setx` command will fail, and proceeding will truncate the `Path`/`GOPATH`. If this happens, it's better to abort, and try to make some more room in `Path` before trying again. + +```text +C:\Users\xxx> set "GOPATH=%USERPROFILE%" +C:\Users\xxx> set "Path=%USERPROFILE%\bin;%Path%" +C:\Users\xxx> setx GOPATH "%GOPATH%" +C:\Users\xxx> setx Path "%Path%" +C:\Users\xxx> mkdir src\github.com\ethereum +C:\Users\xxx> git clone https://github.com/ethereum/go-ethereum src\github.com\ethereum\go-ethereum +C:\Users\xxx> cd src\github.com\ethereum\go-ethereum +C:\Users\xxx> go get -u -v golang.org/x/net/context +``` + +Finally, the command to compile geth is: + +```text +C:\Users\xxx\src\github.com\ethereum\go-ethereum> go install -v ./cmd/... +``` \ No newline at end of file diff --git a/docs/Installing-Geth.md b/docs/Installing-Geth.md new file mode 100644 index 0000000000..0c96726128 --- /dev/null +++ b/docs/Installing-Geth.md @@ -0,0 +1,111 @@ +The Go implementation of Ethereum can be installed using a variety of ways. These include obtaining it as part of Mist; installing it via your favorite package manager; downloading a standalone pre-built bundle; running as a docker container; or building it yourself. This document will detail all of these possibilities to get you quickly joining the Ethereum network using whatever means you prefer. + + * [Install from a package manager](#install-from-a-package-manager) + * [Install on macOS via Homebrew](#install-on-macos-via-homebrew) + * [Install on Ubuntu via PPAs](#install-on-ubuntu-via-ppas) + * [Install on Windows via Chocolatey](#install-on-windows-via-chocolatey) + * [Download standalone bundle](#download-standalone-bundle) + * [Run inside docker container](#run-inside-docker-container) + * [Build it from source code](#build-it-from-source-code) + * [Building without a Go workflow](#building-without-a-go-workflow) + +## Install from a package manager + +### Install on macOS via Homebrew + +### Install on Ubuntu via PPAs + +The simplest way to install go-ethereum on Ubuntu distributions is via the built in launchpad PPAs (Personal Package Archives). We provide a single PPA repository that contains both our stable as well as our develop releases for Ubuntu versions `trusty`, `xenial`, `zesty` and `artful`. + +To enable our launchpad repository please run: + +``` +sudo add-apt-repository -y ppa:ethereum/ethereum +``` + +After that you can install the stable version of Go Ethereum: + +``` +sudo apt-get update +sudo apt-get install ethereum +``` + +Or the develop version via: + +``` +sudo apt-get update +sudo apt-get install ethereum-unstable +``` + +### Install on Windows via Chocolatey + +Although we were shipping Chocolatey packages for a time after Frontier, it has fallen out of date due to the constant manual approval process. With our new build infrastructure in place we will attempt to negotiate trusted package status for go-ethereum to be able to reinstate the Chocolatey workflow. Until then please grab a Windows installer from our [downloads](https://geth.ethereum.org/downloads) page. + +## Download standalone bundle + +All our stable releases and develop builds are distributed as standalone bundles too. These can be useful for scenarios where you'd like to: a) install a specific version of our code (e.g. for reproducible environments); b) install on machines without internet access (e.g. air gapped computers); or c) simply do not like automatic updates and would rather manually install software. + +We create the following standalone bundles: + + * 32bit, 64bit, ARMv5, ARMv6, ARMv7 and ARM64 archives (`.tar.gz`) on Linux + * 64bit archives (`.tar.gz`) on macOS + * 32bit and 64bit archives (`.zip`) and installers (`.exe`) on Windows + +For all archives we provide separate ones containing only Geth, and separate ones containing Geth along with all the developer tools from our repository (`abigen`, `bootnode`, `disasm`, `evm`, `rlpdump`). Please see our [`README`](https://github.com/ethereum/go-ethereum#executables) for more information about these executables. + +To download these bundles, please head the [Go Ethereum Downloads](https://geth.ethereum.org/downloads) page. + +## Run inside docker container + +If you prefer containerized processes, you can run go-ethereum as a docker container too. We currently maintain four different docker images for running the latest stable or develop versions of Geth. + + * `ethereum/client-go:latest` is the latest develop version of Geth + * `ethereum/client-go:stable` is the latest stable version of Geth + * `ethereum/client-go:{version}` is the stable version of Geth at a specific version number + * `ethereum/client-go:release-{version}` is the latest stable version of Geth at a specific version family + +We also maintain four different docker images for running the latest stable or develop versions of miscellaneous Ethereum tools. + + * `ethereum/client-go:alltools-latest` is the latest develop version of the Ethereum tools + * `ethereum/client-go:alltools-stable` is the latest stable version of the Ethereum tools + * `ethereum/client-go:alltools-{version}` is the stable version of the Ethereum tools at a specific version number + * `ethereum/client-go:alltools-release-{version}` is the latest stable version of the Ethereum tools at a specific version family + +The image has the following ports automatically exposed: + + * `8545` TCP, used by the HTTP based JSON RPC API + * `8546` TCP, used by the WebSocket based JSON RPC API + * `30303` TCP and UDP, used by the P2P protocol running the network + * `30304` UDP, used by the P2P protocol's new peer discovery overlay + +*Note, if you are running an Ethereum client inside a docker container, you might want to mount in a data volume as the client's data directory (located at `/root/.ethereum` inside the container) to ensure that downloaded data is preserved between restarts and/or container life-cycles.* + +## Build it from source code + +Go Ethereum (as its name implies) is written in [Go](https://golang.org), and as such to build from source code you'll need to ensure that you have at least Go 1.7 installed (preferably the latest version, currently at 1.9.2). This guide will not go into details on how to install Go itself, for that please consult the [Go installation instructions](https://golang.org/doc/install) and grab any needed bundles from the [Go download page](https://golang.org/dl/). + +Assuming you have Go installed, you can download our project via: + +``` +go get -d github.com/ethereum/go-ethereum +``` + +The above command will checkout the default version of Go Ethereum into your local `GOPATH` work space, but it will not build any executables for you. To do that you can either build one specifically: + +``` +go install github.com/ethereum/go-ethereum/cmd/geth +``` + +Or you can also build the entire project and install `geth` along with all developer tools by running `go install ./...` in the repository root inside your `GOPATH` work space. + +### Building without a Go workflow + +If you do not want to set up Go work spaces on your machine, only build `geth` and forget about the build process, you can clone our repository directly into a folder of your choosing and invoke `make`, which will configure everything for a temporary build and clean up after itself: + +``` +git clone https://github.com/ethereum/go-ethereum.git +cd go-ethereum +make geth +``` + +This will create a `geth` (or `geth.exe` on Windows) executable file in the `go-ethereum/build/bin` folder that you can move wherever you want to run from. The binary is standalone and doesn't require any additional files. \ No newline at end of file diff --git a/docs/Installing-Go.md b/docs/Installing-Go.md new file mode 100644 index 0000000000..5c3b3bd5f0 --- /dev/null +++ b/docs/Installing-Go.md @@ -0,0 +1,37 @@ +### Windows + +Download and run the installer found at http://golang.org/doc/install + +### OS X + +Download an install the darwin binary from https://golang.org/dl/ + +You can also install go using the Homebrew package manager. + +### Linux + +#### Ubuntu + +The Ubuntu repositories carry an old version of Go. + +Ubuntu users can use the 'gophers' PPA to install an up to date version of Go (version 1.7 or later is preferred). +See https://launchpad.net/~gophers/+archive/ubuntu/archive for more information. +Note that this PPA requires adding `/usr/lib/go-1.X/bin` to the executable PATH. + +#### Other distros + +Download the latest distribution + +`curl -O https://storage.googleapis.com/golang/go1.7.3.linux-amd64.tar.gz` + +Unpack it to the `/usr/local` (might require sudo) + +`tar -C /usr/local -xzf go1.7.3.linux-amd64.tar.gz` + +#### Set GOPATH and PATH + +For Go to work properly, you need to set the following two environment variables: + +- Setup a go folder `mkdir -p ~/go; echo "export GOPATH=$HOME/go" >> ~/.bashrc` +- Update your path `echo "export PATH=$PATH:$HOME/go/bin:/usr/local/go/bin" >> ~/.bashrc` +- Read the environment variables into current session: `source ~/.bashrc` \ No newline at end of file diff --git a/docs/Issue-handling-workflow.md b/docs/Issue-handling-workflow.md new file mode 100644 index 0000000000..e7c4c85960 --- /dev/null +++ b/docs/Issue-handling-workflow.md @@ -0,0 +1,51 @@ +### (Draft proposal) +Keep the number of open issues under 820 + +Keep the ratio of open issues per all issues under 13% + +Have 50 issues labelled [help wanted](https://github.com/ethereum/go-ethereum/labels/help%20wanted) and 50 [good first issue](https://github.com/ethereum/go-ethereum/labels/good%20first%20issue). + +Use structured labels of the form `: