mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
delete legacy documents
This commit is contained in:
parent
f6ca03156f
commit
75f0276eed
13 changed files with 0 additions and 1387 deletions
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
title: Active go-ethereum projects
|
|
||||||
---
|
|
||||||
## Direction of development until the end of 2018
|
|
||||||
|
|
||||||
- Clef: move account management out of geth to clef
|
|
||||||
- Constantinople - Tools for testing
|
|
||||||
- Automate cross-client testing
|
|
||||||
- Progpow (ASIC-resistent PoW algorithm)
|
|
||||||
- Ethereum Node Report
|
|
||||||
- Topic discovery
|
|
||||||
- Build an end-to-end test system
|
|
||||||
- Simple API for LES-protocol
|
|
||||||
- Loadbalance tests using Swarm team's network simulator
|
|
||||||
- Test FlowControl subsystem rewrite
|
|
||||||
- Clients get more bandwidth with micro-payment
|
|
||||||
- Database IO reductions
|
|
||||||
- Historical state pruning
|
|
||||||
- Next gen sync algo (cross client)
|
|
||||||
- Blockscout for Puppeth
|
|
||||||
- Contract based signers for Clique (v1.5)
|
|
||||||
- Rinkeby - improve maintenance
|
|
||||||
- Concurrent tx execution experiment
|
|
||||||
- Dashboard
|
|
||||||
- Hive - Devp2p basic tests running as Hive simulation
|
|
||||||
- Hive - Devp2p network tests (different clients peering)
|
|
||||||
- Hive - Add all known client implementations
|
|
||||||
- Hive - Public metrics/test failures page
|
|
||||||
- DevP2P - Document protocols
|
|
||||||
- Hive - Further tests for networked consensus
|
|
||||||
- Discovery - Work with Felix to get ENR/next discovery out asap
|
|
||||||
- Countable trie experiment - For better sync statistic and futher storage rent
|
|
||||||
- Build an end-to-end test system
|
|
||||||
- Finalize simple checkpoint syncing
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
---
|
|
||||||
title: Mobile Clients
|
|
||||||
---
|
|
||||||
**This page has been obsoleted. An new guide is in the progress at [[Mobile: Introduction]]**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*This page is meant to be a guide on using go-ethereum from mobile platforms. Since neither the mobile libraries nor the light client protocol is finalized, the content here will be sparse, with emphasis being put on how to get your hands dirty. As the APIs stabilize this section will be expanded accordingly.*
|
|
||||||
|
|
||||||
### Changelog
|
|
||||||
|
|
||||||
* 30th September, 2016: Create initial page, upload Android light bundle.
|
|
||||||
|
|
||||||
### Background
|
|
||||||
|
|
||||||
Before reading further, please skim through the slides of a Devcon2 talk: [Import Geth: Ethereum from Go and beyond](https://ethereum.karalabe.com/talks/2016-devcon.html), which introduces the basic concepts behind using go-ethereum as a library, and also showcases a few code snippets on how you can do various client side tasks, both on classical computing nodes as well as Android devices. A recording of the talk will be linked when available.
|
|
||||||
|
|
||||||
*Please note, the Android and iOS library bundles linked in the presentation will not be updated (for obvious posterity reasons), so always grab latest bundles from this page (until everything is merged into the proper build infrastructure).*
|
|
||||||
|
|
||||||
### Mobile bundles
|
|
||||||
|
|
||||||
You can download the latest bundles at:
|
|
||||||
|
|
||||||
* [Android (30th September, 2016)](https://bintray.com/karalabe/ethereum/download_file?file_path=geth.aar) - `SHA1: 753e334bf61fa519bec83bcb487179e36d58fc3a`
|
|
||||||
* iOS: *light client has not yet been bundled*
|
|
||||||
|
|
||||||
### Android quickstart
|
|
||||||
|
|
||||||
We assume you are using Android Studio for your development. Please download the latest Android `.aar` bundle from above and import it into your Android Studio project via `File -> New -> New Module`. This will result in a `geth` sub-project inside your work-space. To use the library in your project, please modify your apps `build.gradle` file, adding a dependency to the Geth library:
|
|
||||||
|
|
||||||
```gradle
|
|
||||||
dependencies {
|
|
||||||
// All your previous dependencies
|
|
||||||
compile project(':geth')
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
To get you hands dirty, here's a code snippet that will
|
|
||||||
|
|
||||||
* Start up an in-process light node inside your Android application
|
|
||||||
* Display some initial infos about your node
|
|
||||||
* Subscribe to new blocks and display them live as they arrive
|
|
||||||
|
|
||||||
<img src="http://i.imgur.com/LyTCCqg.png" width="512px" alt="Android in-process node"/>
|
|
||||||
|
|
||||||
```java
|
|
||||||
import org.ethereum.geth.*;
|
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_main);
|
|
||||||
|
|
||||||
setTitle("Android In-Process Node");
|
|
||||||
final TextView textbox = (TextView) findViewById(R.id.textbox);
|
|
||||||
|
|
||||||
Context ctx = new Context();
|
|
||||||
|
|
||||||
try {
|
|
||||||
Node node = Geth.newNode(getFilesDir() + "/.ethereum", new NodeConfig());
|
|
||||||
node.start();
|
|
||||||
|
|
||||||
NodeInfo info = node.getNodeInfo();
|
|
||||||
textbox.append("My name: " + info.getName() + "\n");
|
|
||||||
textbox.append("My address: " + info.getListenerAddress() + "\n");
|
|
||||||
textbox.append("My protocols: " + info.getProtocols() + "\n\n");
|
|
||||||
|
|
||||||
EthereumClient ec = node.getEthereumClient();
|
|
||||||
textbox.append("Latest block: " + ec.getBlockByNumber(ctx, -1).getNumber() + ", syncing...\n");
|
|
||||||
|
|
||||||
NewHeadHandler handler = new NewHeadHandler() {
|
|
||||||
@Override public void onError(String error) { }
|
|
||||||
@Override public void onNewHead(final Header header) {
|
|
||||||
MainActivity.this.runOnUiThread(new Runnable() {
|
|
||||||
public void run() { textbox.append("#" + header.getNumber() + ": " + header.getHash().getHex().substring(0, 10) + ".\n"); }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ec.subscribeNewHead(ctx, handler, 16);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Known quirks
|
|
||||||
|
|
||||||
* Many constructors (those that would throw exceptions) are of the form `Geth.newXXX()`, instead of simply the Java style `new XXX()` This is an upstream limitation of the [gomobile](https://github.com/golang/mobile) project, one which is currently being worked on to resolve.
|
|
||||||
* There are zero documentations attached to the Java library methods. This too is a limitation of the [gomobile](https://github.com/golang/mobile) project. We will try to propose a fix upstream to make our docs from the Go codebase available in Java.
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
---
|
|
||||||
title: Gas price oracle
|
|
||||||
---
|
|
||||||
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.
|
|
||||||
|
|
@ -1,397 +0,0 @@
|
||||||
---
|
|
||||||
title: Contracts and transactions (Japanese)
|
|
||||||
---
|
|
||||||
THIS WIKI IS BEING EDITED AND REVIEWED NOW. PLEASE DO NOT RELY ON IT.
|
|
||||||
|
|
||||||
# Account types and transactions
|
|
||||||
|
|
||||||
There are two types of accounts in Ethereum state:
|
|
||||||
* Normal or externally controlled accounts and
|
|
||||||
* contracts, i.e., sinppets of code, think a class.
|
|
||||||
|
|
||||||
Both types of accounts have an ether balance.
|
|
||||||
|
|
||||||
Transactions can be fired from from both types of accounts, though contracts only fire transactions in response to other transactions that they have received. Therefore, all action on ethereum block chain is set in motion by transactions fired from externally controlled accounts.
|
|
||||||
|
|
||||||
The simplest transactions are ether transfer transactions. But before we go into that you should read up on [accounts](../interface/managing-your-accounts) and perhaps on [mining](../legacy/mining).
|
|
||||||
|
|
||||||
## Ether transfer
|
|
||||||
|
|
||||||
Assuming the account you are using as sender has sufficient funds, sending ether couldn't be easier. Which is also why you should probably be careful with this! You have been warned.
|
|
||||||
|
|
||||||
```js
|
|
||||||
eth.sendTransaction({from: '0x036a03fc47084741f83938296a1c8ef67f6e34fa', to: '0xa8ade7feab1ece71446bed25fa0cf6745c19c3d5', value: web3.toWei(1, "ether")})
|
|
||||||
```
|
|
||||||
|
|
||||||
Note the unit conversion in the `value` field. Transaction values are expressed in weis, the most granular units of value. If you want to use some other unit (like `ether` in the example above), use the function `web3.toWei` for conversion.
|
|
||||||
|
|
||||||
Also, be advised that the amount debited from the source account will be slightly larger than that credited to the target account, which is what has been specified. The difference is a small transaction fee, discussed in more detail later.
|
|
||||||
|
|
||||||
Contracts can receive transfers just like externally controlled accounts, but they can also receive more complicated transactions that actually run (parts of) their code and update their state. In order to understand those transactions, a rudimentary understanding of contracts is required.
|
|
||||||
|
|
||||||
# contract のコンパイル
|
|
||||||
|
|
||||||
blockchain 上で有効となる contract は Ethereum 特別仕様の バイナリの形式で、EVM byte コード と呼ばれます。
|
|
||||||
しかしながら、典型的には、contract は [solidity](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial) のような高級言語で記述され、blockchain 上に upload するために、この byte コードへコンパイルされます。
|
|
||||||
|
|
||||||
flontier リリースでは、geth は Christian R. と Lefteris K が手がけた、コマンドライン [solidity コンパイラ](https://solidity.readthedocs.io/en/latest/installing-solidity.html) である `solc` をシステムコールで呼び出すことを通して、solidity コンパイルをサポートしています。
|
|
||||||
以下もお試しください。
|
|
||||||
* [Solidity realtime compiler](https://chriseth.github.io/cpp-ethereum/) (by Christian R)
|
|
||||||
* [Cosmo](https://github.com/cosmo-project/meteor-dapp-cosmo)
|
|
||||||
* [Mix]()
|
|
||||||
* [AlethZero]()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Note that other languages also exist, notably [serpent]() and [lll]().
|
|
||||||
|
|
||||||
If you start up your `geth` node, you can check if this option is immediately available. This is what happens, if it is not:
|
|
||||||
|
|
||||||
```js
|
|
||||||
eth.getCompilers()
|
|
||||||
['' ]
|
|
||||||
> eth.compile.solidity("")
|
|
||||||
error: eth_compileSolidity method not implemented
|
|
||||||
Invalid JSON RPC response
|
|
||||||
```
|
|
||||||
|
|
||||||
After you found a way to install `solc`, you make sure it's in the path, if [`eth.getCompilers()`](https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethgetcompilers) still does not find it (returns an empty array), you can set a custom path to the `sol` executable on the command line using th `solc` flag.
|
|
||||||
|
|
||||||
```
|
|
||||||
geth --datadir ~/frontier/00 --solc /usr/local/bin/solc --natspec
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also set this option at runtime via the console:
|
|
||||||
|
|
||||||
```js
|
|
||||||
> admin.setSolc("/usr/local/bin/solc")
|
|
||||||
solc v0.9.13
|
|
||||||
Solidity Compiler: /usr/local/bin/solc
|
|
||||||
Christian <c@ethdev.com> and Lefteris <lefteris@ethdev.com> (c) 2014-2015
|
|
||||||
true
|
|
||||||
```
|
|
||||||
|
|
||||||
Let us take this simple contract source:
|
|
||||||
|
|
||||||
```js
|
|
||||||
> source = "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
|
|
||||||
```
|
|
||||||
|
|
||||||
This contract offers a unary method: called with a positive integer `a`, it returns `a * 7`.
|
|
||||||
Note that this document is not about writing interesting contracts or about the features of solidity.
|
|
||||||
|
|
||||||
For more information on contract language, go through [solidity tutorial](https://github.com/ethereum/wiki/wiki/Solidity-Tutorial), browse the contracts in our [dapp-bin](https://github.com/ethereum/dapp-bin/wiki), see other solidity and dapp resources.
|
|
||||||
|
|
||||||
You are ready to compile solidity code in the `geth` JS console using [`eth.compile.solidity`](https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethcompilesolidity):
|
|
||||||
|
|
||||||
```js
|
|
||||||
> contract = eth.compile.solidity(source)
|
|
||||||
{
|
|
||||||
code: '605280600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b60376004356041565b8060005260206000f35b6000600782029050604d565b91905056',
|
|
||||||
info: {
|
|
||||||
language: 'Solidity',
|
|
||||||
languageVersion: '0',
|
|
||||||
compilerVersion: '0.9.13',
|
|
||||||
abiDefinition: [{
|
|
||||||
constant: false,
|
|
||||||
inputs: [{
|
|
||||||
name: 'a',
|
|
||||||
type: 'uint256'
|
|
||||||
} ],
|
|
||||||
name: 'multiply',
|
|
||||||
outputs: [{
|
|
||||||
name: 'd',
|
|
||||||
type: 'uint256'
|
|
||||||
} ],
|
|
||||||
type: 'function'
|
|
||||||
} ],
|
|
||||||
userDoc: {
|
|
||||||
methods: {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
developerDoc: {
|
|
||||||
methods: {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
source: 'contract test { function multiply(uint a) returns(uint d) { return a * 7; } }'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The compiler is also available via [RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) and therefore via [web3.js](https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethcompilesolidity) to any in-browser Ðapp connecting to `geth` via RPC.
|
|
||||||
|
|
||||||
The following example shows how you interface `geth` via JSON-RPC to use the compiler.
|
|
||||||
|
|
||||||
```
|
|
||||||
./geth --datadir ~/eth/ --loglevel 6 --logtostderr=true --rpc --rpcport 8100 --rpccorsdomain '*' --mine console 2>> ~/eth/eth.log
|
|
||||||
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_compileSolidity","params":["contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"],"id":1}' http://127.0.0.1:8100
|
|
||||||
```
|
|
||||||
|
|
||||||
The compiler output is combined into an object representing a single contract and is serialised as json. It contains the following fields:
|
|
||||||
|
|
||||||
* `code`: the compiled EVM code
|
|
||||||
* `source`: the source code
|
|
||||||
* `language`: contract language (Solidity, Serpent, LLL)
|
|
||||||
* `languageVersion`: contract language version
|
|
||||||
* `compilerVersion`: compiler version
|
|
||||||
* `abiDefinition`: [Application Binary Interface Definition](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI)
|
|
||||||
* `userDoc`: [NatSpec user Doc](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format)
|
|
||||||
* `developerDoc`: [NatSpec developer Doc](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format)
|
|
||||||
|
|
||||||
The immediate structuring of the compiler output (into `code` and `info`) reflects the two very different **paths of deployment**.
|
|
||||||
The compiled EVM code is sent off to the blockchain with a contract creation transaction while the rest (info) will ideally live on the decentralised cloud as publicly verifiable metadata complementing the code on the blockchain.
|
|
||||||
|
|
||||||
# Creating and deploying a contract
|
|
||||||
|
|
||||||
Now that you got both an unlocked account as well as some funds, you can create a contract on the blockchain by [sending a transaction](https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethsendtransaction) to the empty address with the evm code as data. Simple, eh?
|
|
||||||
|
|
||||||
```js
|
|
||||||
primaryAddress = eth.accounts[0]
|
|
||||||
contractAddress = eth.sendTransaction({from: primaryAddress, data: evmCode})
|
|
||||||
```
|
|
||||||
|
|
||||||
All binary data is serialised in hexadecimal form. Hex strings always have a hex prefix `0x`.
|
|
||||||
|
|
||||||
Note that this step requires you to pay for execution. Your balance on the account (that you put as sender in the `from` field) will be reduced according to the gas rules of the VM once your transaction makes it into a block. More on that later. After some time, your transaction should appear included in a block confirming that the state it brought about is a consensus. Your contract now lives on the blockchain.
|
|
||||||
|
|
||||||
The asynchronous way of doing the same looks like this:
|
|
||||||
|
|
||||||
```js
|
|
||||||
eth.sendTransaction({from: primaryAccount, data: evmCode}, function(err, address) {
|
|
||||||
if (!err)
|
|
||||||
console.log(address);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
# Gas and transaction costs
|
|
||||||
|
|
||||||
So how did you pay for all this? Under the hood, the transaction specified a gas limit and a gasprice, both of which could have been specified directly in the transaction object.
|
|
||||||
|
|
||||||
Gas limit is there to protect you from buggy code running until your funds are depleted. The product of `gasPrice` and `gas` represents the maximum amount of Wei that you are willing to pay for executing the transaction. What you specify as `gasPrice` is used by miners to rank transactions for inclusion in the blockchain. It is the price in Wei of one unit of gas, in which VM operations are priced.
|
|
||||||
|
|
||||||
The gas expenditure incurred by running your contract will be bought by the ether you have in your account at a price you specified in the transaction with `gasPrice`. If you do not have the ether to cover all the gas requirements to complete running your code, the processing aborts and all intermediate state changes roll back to the pre-transaction snapshot. The gas used up to the point where execution stopped were used after all, so the ether balance of your account will be reduced. These parameters can be adjusted on the transaction object fields `gas` and `gasPrice`. The `value` field is used the same as in ether transfer transactions between normal accounts. In other words transferring funds is available between any two accounts, either normal (i.e. externally controlled) or contract. If your contract runs out of funds, you should see an insufficient funds error. Note that all funds on contract accounts will be irrecoverably lost, once we release Homestead.
|
|
||||||
|
|
||||||
For testing and playing with contracts you can use the test network or set up a private node (or cluster) potentially isolated from all the other nodes. If you then mine, you can make sure that your transaction will be included in the next block. You can see the pending transactions with:
|
|
||||||
|
|
||||||
```js
|
|
||||||
eth.getBlock("pending", true).transactions
|
|
||||||
```
|
|
||||||
|
|
||||||
You can retrieve blocks by number (height) or by their hash:
|
|
||||||
|
|
||||||
```js
|
|
||||||
genesis = eth.getBlock(0)
|
|
||||||
eth.getBlock(genesis.hash).hash == genesis.hash
|
|
||||||
true
|
|
||||||
```
|
|
||||||
|
|
||||||
Use `eth.blockNumber` to get the current blockchain height and the "latest" magic parameter to access the current head (newest block).
|
|
||||||
|
|
||||||
```js
|
|
||||||
currentHeight = eth.blockNumber()
|
|
||||||
eth.getBlock("latest").hash == eth.getBlock(eth.blockNumber).hash
|
|
||||||
true
|
|
||||||
```
|
|
||||||
|
|
||||||
# Contract info (metadata)
|
|
||||||
|
|
||||||
In the previous sections we explained how you create a contract on the blockchain. Now we deal with the rest of the compiler output, the **contract metadata** or contract info.
|
|
||||||
The idea is that
|
|
||||||
|
|
||||||
* contract info is uploaded somewhere identifiable by a `url` which is publicly accessible
|
|
||||||
* anyone can find out what the `url` is only knowing the contracts address
|
|
||||||
|
|
||||||
These requirements are achieved very simply by using a 2 step blockchain registry. The first step registers the contract code (hash) with a content hash in a contract called `HashReg`. The second step registers a url with the content hash in the `UrlHint` contract.
|
|
||||||
These [simple registry contracts]() will be part of the frontier proposition.
|
|
||||||
|
|
||||||
By using this scheme, it is sufficient to know a contract's address to look up the url and fetch the actual contract metadata info bundle. Read on to learn why this is good.
|
|
||||||
|
|
||||||
So if you are a conscientious contract creator, the steps are the following:
|
|
||||||
|
|
||||||
1. Get the contract info json file.
|
|
||||||
2. Deploy contract info json file to any url of your choice
|
|
||||||
3. Register codehash ->content hash -> url
|
|
||||||
4. Deploy the contract itself to the blockchain
|
|
||||||
|
|
||||||
The JS API makes this process very easy by providing helpers. Call [`admin.contractInfo.register`]() to extract info from the contract, write out its json serialisation in the given file, calculates the content hash of the file and finally registers this content hash to the contract's code hash.
|
|
||||||
Once you deployed that file to any url, you can use [`admin.contractInfo.registerUrl`]() to register the url with your content hash on the blockchain as well. (Note that in case a fixed content addressed model is used as document store, the url-hint is no longer necessary.)
|
|
||||||
|
|
||||||
```js
|
|
||||||
source = "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
|
|
||||||
// compile with solc
|
|
||||||
contract = eth.compile.solidity(source)
|
|
||||||
// send off the contract to the blockchain
|
|
||||||
address = eth.sendTransaction({from: primaryAccount, data: contract.code})
|
|
||||||
// extracts info from contract, save the json serialisation in the given file,
|
|
||||||
// calculates the content hash and registers it with the code hash in `HashReg`
|
|
||||||
// it uses address to send the transaction.
|
|
||||||
// returns the content hash that we use to register a url
|
|
||||||
hash = admin.contractInfo.register(primaryAccount, address, contract, "~/dapps/shared/contracts/test/info.json")
|
|
||||||
// here you deploy ~/dapps/shared/contracts/test/info.json to a url
|
|
||||||
admin.contractInfo.registerUrl(primaryAccount, hash, url)
|
|
||||||
```
|
|
||||||
|
|
||||||
# Interacting with contracts
|
|
||||||
|
|
||||||
[`eth.contract`](https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethcontract) can be used to define a contract _class_ that will comply with the contract interface as described in its [ABI definition](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI).
|
|
||||||
|
|
||||||
```js
|
|
||||||
var Multiply7 = eth.contract(contract.info.abiDefinition);
|
|
||||||
var multiply7 = new Multiply7(address);
|
|
||||||
```
|
|
||||||
|
|
||||||
Now all the function calls specified in the abi are made available on the contract instance. You can just call those methods on the contract instance and chain `sendTransaction({from: address})` or `call()` to it. The difference between the two is that `call` performs a "dry run" locally, on your computer, while `sendTransaction` would actually submit your transaction for inclusion in the block chain and the results of its execution will eventually become part of the global consensus. In other words, use `call`, if you are interested only in the return value and use `sendTransaction` if you only care about "side effects" on the state of the contract.
|
|
||||||
|
|
||||||
In the example above, there are no side effects, therefore `sendTransaction` only burns gas and increases the entropy of the universe. All "useful" functionality is exposed by `call`:
|
|
||||||
|
|
||||||
```js
|
|
||||||
multiply7.multiply.call(6)
|
|
||||||
42
|
|
||||||
```
|
|
||||||
|
|
||||||
Now suppose this contract is not yours, and you would like documentation or look at the source code.
|
|
||||||
This is made possible by making available the contract info bundle and register it in the blockchain.
|
|
||||||
The `admin.contractInfo` API provides convenience methods to fetch this bundle for any contract that chose to register.
|
|
||||||
To see how it works, read about [Contract Metadata](https://github.com/ethereum/wiki/wiki/Contract-metadata) or read the contract info deployment section of this document.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// get the contract info for contract address to do manual verification
|
|
||||||
var info = admin.contractInfo.get(address) // lookup, fetch, decode
|
|
||||||
var source = info.source;
|
|
||||||
var abiDef = info.abiDefinition
|
|
||||||
```
|
|
||||||
|
|
||||||
```js
|
|
||||||
// verify an existing contract in blockchain (NOT IMPLEMENTED)
|
|
||||||
admin.contractInfo.verify(address)
|
|
||||||
```
|
|
||||||
|
|
||||||
# NatSpec
|
|
||||||
|
|
||||||
This section will further elaborate what you can do with contracts and transactions building on a protocol NatSpec. Solidity implements smart comments doxigen style which then can be used to generate various facades meta documents of the code. One such use case is to generate custom messages for transaction confirmation that clients can prompt users with.
|
|
||||||
|
|
||||||
So we now extend the `multiply7` contract with a smart comment specifying a custom confirmation message (notice).
|
|
||||||
|
|
||||||
```js
|
|
||||||
contract test {
|
|
||||||
/// @notice Will multiply `a` by 7.
|
|
||||||
function multiply(uint a) returns(uint d) {
|
|
||||||
return a * 7;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The comment has expressions in between backticks which are to be evaluated at the time the transaction confirmation message is presented to the user. The variables that refer to parameters of method calls then are instantiated in accordance with the actual transaction data sent by the user (or the user's dapp). NatSpec support for confirmation notices is fully implemented in `geth`. NatSpec relies on both the abi definition as well as the userDoc component to generate the proper confirmations. Therefore in order to access that, the contract needs to have registered its contract info as described above.
|
|
||||||
|
|
||||||
Let us see a full example. As a very conscientious smart contract dev, you first create your contract and deploy according to the recommended steps above:
|
|
||||||
|
|
||||||
```js
|
|
||||||
source = "contract test {
|
|
||||||
/// @notice Will multiply `a` by 7.
|
|
||||||
function multiply(uint a) returns(uint d) {
|
|
||||||
return a * 7;
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
contract = eth.compile.solidity(source)
|
|
||||||
contentHash = admin.contractInfo.register(contract, "~/dapps/shared/contracts/test/info.json")
|
|
||||||
// put it up on your favourite site:
|
|
||||||
admin.contractInfo.registerUrl(contentHash, "http://dapphub.com/test/info.json")
|
|
||||||
```
|
|
||||||
|
|
||||||
For the purposes of a painless example just simply use the file url scheme (not exactly the cloud, but will show you how it works) without needing to deploy. `admin.contractInfo.registerUrl(contentHash, "file:///home/nirname/dapps/shared/contracts/test/info.json")`.
|
|
||||||
|
|
||||||
Now you are done as a dev, so swap seats as it were and pretend that you are a user who is sending a transaction to the infamous multiply7 contract.
|
|
||||||
|
|
||||||
You need to start the client with the `--natspec` flag to enable smart confirmations and contractInfo fetching. You can also set it on the console with `admin.contractInfo.start()` and `admin.contractInfo.stop()`.
|
|
||||||
|
|
||||||
```
|
|
||||||
geth --natspec --unlock primary console 2>> /tmp/eth.log
|
|
||||||
```
|
|
||||||
|
|
||||||
Now at the console type:
|
|
||||||
|
|
||||||
```js
|
|
||||||
// obtain the abi definition for your contract
|
|
||||||
var info = admin.contractInfo.get(address)
|
|
||||||
var abiDef = info.abiDefinition
|
|
||||||
// instantiate a contract for transactions
|
|
||||||
var Multiply7 = eth.contract(abiDef);
|
|
||||||
var multiply7 = new Multiply7();
|
|
||||||
```
|
|
||||||
|
|
||||||
And now try to send an actual transaction:
|
|
||||||
|
|
||||||
```js
|
|
||||||
> multiply7.multiply.sendTransaction(6)
|
|
||||||
NatSpec: Will multiply 6 by 7.
|
|
||||||
Confirm? [Y/N] y
|
|
||||||
>
|
|
||||||
```
|
|
||||||
|
|
||||||
When this transaction gets included in a block, somewhere on a lucky miner's computer, 6 will get multiplied by 7, with the result ignored.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// assume an existing unlocked primary account
|
|
||||||
primary = eth.accounts[0];
|
|
||||||
|
|
||||||
// mine 10 blocks to generate ether
|
|
||||||
admin.miner.start();
|
|
||||||
admin.debug.waitForBlocks(eth.blockNumber+10);
|
|
||||||
admin.miner.stop() ;
|
|
||||||
|
|
||||||
balance = web3.fromWei(eth.getBalance(primary), "ether");
|
|
||||||
|
|
||||||
admin.contractInfo.newRegistry(primary);
|
|
||||||
|
|
||||||
source = "contract test {\n" +
|
|
||||||
" /// @notice will multiply `a` by 7.\n" +
|
|
||||||
" function multiply(uint a) returns(uint d) {\n" +
|
|
||||||
" return a * 7;\n" +
|
|
||||||
" }\n" +
|
|
||||||
"} ";
|
|
||||||
|
|
||||||
contract = eth.compile.solidity(source);
|
|
||||||
|
|
||||||
contractaddress = eth.sendTransaction({from: primary, data: contract.code});
|
|
||||||
|
|
||||||
eth.getBlock("pending", true).transactions;
|
|
||||||
|
|
||||||
admin.miner.start()
|
|
||||||
// waits until block height is minimum the number given.
|
|
||||||
// basically a sleep function on variable block units of time.
|
|
||||||
|
|
||||||
admin.debug.waitForBlocks(eth.blockNumber+1);
|
|
||||||
admin.miner.stop()
|
|
||||||
|
|
||||||
code = eth.getCode(contractaddress);
|
|
||||||
|
|
||||||
abiDef = JSON.parse('[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]');
|
|
||||||
Multiply7 = eth.contract(abiDef);
|
|
||||||
multiply7 = new Multiply7(contractaddress);
|
|
||||||
|
|
||||||
fortytwo = multiply7.multiply.call(6);
|
|
||||||
console.log("multiply7.multiply.call(6) => "+fortytwo);
|
|
||||||
multiply7.multiply.sendTransaction(6, {from: primary})
|
|
||||||
|
|
||||||
admin.miner.start();
|
|
||||||
admin.debug.waitForBlocks(eth.blockNumber+1);
|
|
||||||
admin.miner.stop();
|
|
||||||
|
|
||||||
filename = "/tmp/info.json";
|
|
||||||
contenthash = admin.contractInfo.register(primary, contractaddress, contract, filename);
|
|
||||||
|
|
||||||
admin.contractInfo.registerUrl(primary, contenthash, "file://"+filename);
|
|
||||||
|
|
||||||
admin.miner.start();
|
|
||||||
admin.debug.waitForBlocks(eth.blockNumber+1);
|
|
||||||
admin.miner.stop();
|
|
||||||
|
|
||||||
info = admin.contractInfo.get(contractaddress);
|
|
||||||
|
|
||||||
admin.contractInfo.start();
|
|
||||||
abiDef = JSON.parse('[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]');
|
|
||||||
Multiply7 = eth.contract(abiDef);
|
|
||||||
multiply7 = new Multiply7(contractaddress);
|
|
||||||
fortytwo = multiply7.multiply.sendTransaction(6, { from: primary });
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
---
|
|
||||||
title: Provisional JS API
|
|
||||||
---
|
|
||||||
The *provisional* JavaScript API is a purposed API for all things JavaScript. JavaScript technologies can be embedded within Qt(QML) technologies, local web and remote web and therefor the purposed API is written in a ASYNC fashion so that it may be used across all implementations. Hereby it should be known that all functions, unless explicitly specified, take a callback as last function argument which will be called when the operation has been completed.
|
|
||||||
|
|
||||||
Please note that the provisional JavaScript API tries to leverage existing JS idioms as much as possible.
|
|
||||||
|
|
||||||
## General API
|
|
||||||
|
|
||||||
* `getBlock (number or string)`
|
|
||||||
Retrieves a block by either the address or the number. If supplied with a string it will assume address, number otherwise.
|
|
||||||
* `transact (sec, recipient, value, gas, gas price, data)`
|
|
||||||
Creates a new transaction using your current key.
|
|
||||||
* `create (sec, value, gas, gas price, init, body)`
|
|
||||||
Creates a new contract using your current key.
|
|
||||||
* `getKey (none)`
|
|
||||||
Retrieves your current key in hex format.
|
|
||||||
* `getStorage (object address, storage address)`
|
|
||||||
Retrieves the storage address of the given object.
|
|
||||||
* `getBalance (object address)`
|
|
||||||
Retrieves the balance at the current address
|
|
||||||
* `watch (string [, string])`
|
|
||||||
Watches for changes on a specific address' state object such as state root changes or value changes.
|
|
||||||
* `disconnect (string [, string])`
|
|
||||||
Disconnects from a previous `watched` address.
|
|
||||||
|
|
||||||
## Events
|
|
||||||
|
|
||||||
The provisional JavaScript API exposes certain events through a basic eventing mechanism inspired by jQuery.
|
|
||||||
|
|
||||||
* `on (event)`
|
|
||||||
Subscribe to event which will be called whenever an event of type <event> is received.
|
|
||||||
* `off (event)`
|
|
||||||
Unsubscribe to the given event
|
|
||||||
* `trigger (event, data)`
|
|
||||||
Trigger event of type <event> with the given data. **note:** This function does not take a callback function.
|
|
||||||
|
|
||||||
### Event Types
|
|
||||||
|
|
||||||
All events are written in camel cased style beginning with a lowercase letter. Subevents are denoted by a colon `:`.
|
|
||||||
|
|
||||||
* `block:new`
|
|
||||||
Fired when a new valid block has been found on the wire. The attached value of this call is a block.
|
|
||||||
* `object:changed`
|
|
||||||
Fired when a watched address, specified through `watch`, changes in value.
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
---
|
|
||||||
title: Sending ether
|
|
||||||
---
|
|
||||||
|
|
||||||
The basic way of sending a simple transaction of ether with the console is as follows:
|
|
||||||
```js
|
|
||||||
> eth.sendTransaction({from:sender, to:receiver, value: amount})
|
|
||||||
```
|
|
||||||
|
|
||||||
Using the built-in JavaScript, you can easily set variables to hold these values. For example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
> var sender = eth.accounts[0];
|
|
||||||
> var receiver = eth.accounts[1];
|
|
||||||
> var amount = web3.toWei(0.01, "ether")
|
|
||||||
```
|
|
||||||
|
|
||||||
Alternatively, you can compose a transaction in a single line with:
|
|
||||||
|
|
||||||
```js
|
|
||||||
> eth.sendTransaction({from:eth.coinbase, to:eth.accounts[1], value: web3.toWei(0.05, "ether")})
|
|
||||||
Please unlock account d1ade25ccd3d550a7eb532ac759cac7be09c2719.
|
|
||||||
Passphrase:
|
|
||||||
Account is now unlocked for this session.
|
|
||||||
'0xeeb66b211e7d9be55232ed70c2ebb1bcc5d5fd9ed01d876fac5cff45b5bf8bf4'
|
|
||||||
```
|
|
||||||
|
|
||||||
The resulting transaction is `0xeeb66b211e7d9be55232ed70c2ebb1bcc5d5fd9ed01d876fac5cff45b5bf8bf4`
|
|
||||||
|
|
||||||
If the password was incorrect you will instead receive an error:
|
|
||||||
```js
|
|
||||||
error: could not unlock sender account
|
|
||||||
```
|
|
||||||
|
|
@ -1,119 +0,0 @@
|
||||||
---
|
|
||||||
title: Setting up private network or local cluster
|
|
||||||
---
|
|
||||||
This page describes how to set up a local cluster of nodes, advise how to make it private, and how to hook up your nodes on the eth-netstat network monitoring app.
|
|
||||||
A fully controlled ethereum network is useful as a backend for network integration testing (core developers working on issues related to networking/blockchain synching/message propagation, etc or DAPP developers testing multi-block and multi-user scenarios).
|
|
||||||
|
|
||||||
We assume you are able to build `geth` following the [build instructions](../install-and-build/build-from-source)
|
|
||||||
|
|
||||||
## Setting up multiple nodes
|
|
||||||
|
|
||||||
In order to run multiple ethereum nodes locally, you have to make sure:
|
|
||||||
- each instance has a separate data directory (`--datadir`)
|
|
||||||
- each instance runs on a different port (both eth and rpc) (`--port and --rpcport`)
|
|
||||||
- in case of a cluster the instances must know about each other
|
|
||||||
- the ipc endpoint is unique or the ipc interface is disabled (`--ipcpath or --ipcdisable`)
|
|
||||||
|
|
||||||
You start the first node (let's make port explicit and disable ipc interface)
|
|
||||||
```bash
|
|
||||||
geth --datadir="/tmp/eth/60/01" -verbosity 6 --ipcdisable --port 30301 --rpcport 8101 console 2>> /tmp/eth/60/01.log
|
|
||||||
```
|
|
||||||
|
|
||||||
We started the node with the console, so that we can grab the enode url for instance:
|
|
||||||
|
|
||||||
```
|
|
||||||
> admin.nodeInfo.enode
|
|
||||||
enode://8c544b4a07da02a9ee024def6f3ba24b2747272b64e16ec5dd6b17b55992f8980b77938155169d9d33807e501729ecb42f5c0a61018898c32799ced152e9f0d7@9[::]:30301
|
|
||||||
```
|
|
||||||
|
|
||||||
`[::]` will be parsed as localhost (`127.0.0.1`). If your nodes are on a local network check each individual host machine and find your ip with `ifconfig` (on Linux and MacOS):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ ifconfig|grep netmask|awk '{print $2}'
|
|
||||||
127.0.0.1
|
|
||||||
192.168.1.97
|
|
||||||
```
|
|
||||||
|
|
||||||
If your peers are not on the local network, you need to know your external IP address (use a service) to construct the enode url.
|
|
||||||
|
|
||||||
Now you can launch a second node with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
geth --datadir="/tmp/eth/60/02" --verbosity 6 --ipcdisable --port 30302 --rpcport 8102 console 2>> /tmp/eth/60/02.log
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to connect this instance to the previously started node you can add it as a peer from the console with `admin.addPeer(enodeUrlOfFirstInstance)`.
|
|
||||||
|
|
||||||
You can test the connection by typing in geth console:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
> net.listening
|
|
||||||
true
|
|
||||||
> net.peerCount
|
|
||||||
1
|
|
||||||
> admin.peers
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Local cluster
|
|
||||||
|
|
||||||
As an extention of the above, you can spawn a local cluster of nodes easily. It can also be scripted including account creation which is needed for mining.
|
|
||||||
See [`gethcluster.sh`](https://github.com/ethersphere/eth-utils) script, and the README there for usage and examples.
|
|
||||||
|
|
||||||
## Private network
|
|
||||||
|
|
||||||
See [[the Private Network Page|Private network]] for more information.
|
|
||||||
|
|
||||||
### Setup bootnode
|
|
||||||
|
|
||||||
The first time a node connects to the network it uses one of the predefined [bootnodes](https://github.com/ethereum/go-ethereum/blob/master/params/bootnodes.go). Through these bootnodes a node can join the network and find other nodes. In the case of a private cluster these predefined bootnodes are not of much use. Therefore go-ethereum offers a bootnode implementation that can be configured and run in your private network.
|
|
||||||
|
|
||||||
It can be run through the command.
|
|
||||||
```
|
|
||||||
> bootnode
|
|
||||||
Fatal: Use -nodekey or -nodekeyhex to specify a private key
|
|
||||||
```
|
|
||||||
|
|
||||||
As can be seen the bootnode asks for a key. Each ethereum node, including a bootnode is identified by an enode identifier. These identifiers are derived from a key. Therefore you will need to give the bootnode such key. Since we currently don't have one we can instruct the bootnode to generate a key (and store it in a file) before it starts.
|
|
||||||
|
|
||||||
```
|
|
||||||
> bootnode -genkey bootnode.key
|
|
||||||
I0216 09:53:08.076155 p2p/discover/udp.go:227] Listening, enode://890b6b5367ef6072455fedbd7a24ebac239d442b18c5ab9d26f58a349dad35ee5783a0dd543e4f454fed22db9772efe28a3ed6f21e75674ef6203e47803da682@[::]:30301
|
|
||||||
```
|
|
||||||
|
|
||||||
(exit with CTRL-C)
|
|
||||||
|
|
||||||
The stored key can be seen with:
|
|
||||||
```
|
|
||||||
> cat bootnode.key
|
|
||||||
dc90f8f7324f1cc7ba52c4077721c939f98a628ed17e51266d01c9cd0294033a
|
|
||||||
```
|
|
||||||
|
|
||||||
To instruct geth nodes to use our own bootnode(s) use the `--bootnodes` flag. This is a comma separated list of bootnode enode identifiers.
|
|
||||||
|
|
||||||
```
|
|
||||||
geth --bootnodes "enode://890b6b5367ef6072455fedbd7a24ebac239d442b18c5ab9d26f58a349dad35ee5783a0dd543e4f454fed22db9772efe28a3ed6f21e75674ef6203e47803da682@[::]:30301"
|
|
||||||
```
|
|
||||||
(what [::] means is explained previously)
|
|
||||||
|
|
||||||
Since it is convenient to start the bootnode each time with the same enode we can give the bootnode program the just generated key on the next time it is started.
|
|
||||||
|
|
||||||
```
|
|
||||||
bootnode -nodekey bootnode.key
|
|
||||||
I0216 10:01:19.125600 p2p/discover/udp.go:227] Listening, enode://890b6b5367ef6072455fedbd7a24ebac239d442b18c5ab9d26f58a349dad35ee5783a0dd543e4f454fed22db9772efe28a3ed6f21e75674ef6203e47803da682@[::]:30301
|
|
||||||
```
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
```
|
|
||||||
bootnode -nodekeyhex dc90f8f7324f1cc7ba52c4077721c939f98a628ed17e51266d01c9cd0294033a
|
|
||||||
I0216 10:01:40.094089 p2p/discover/udp.go:227] Listening, enode://890b6b5367ef6072455fedbd7a24ebac239d442b18c5ab9d26f58a349dad35ee5783a0dd543e4f454fed22db9772efe28a3ed6f21e75674ef6203e47803da682@[::]:30301
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Monitoring your nodes
|
|
||||||
|
|
||||||
[This page](https://github.com/ethereum/wiki/wiki/Network-Status) describes how to use the [The Ethereum (centralised) network status monitor (known sometimes as "eth-netstats")](http://stats.ethdev.com) to monitor your nodes.
|
|
||||||
|
|
||||||
[This page](../doc/setting-up-monitoring-on-local-cluster) or [this README](https://github.com/ethersphere/eth-utils)
|
|
||||||
describes how you set up your own monitoring service for a (private or public) local cluster.
|
|
||||||
|
|
@ -1,270 +0,0 @@
|
||||||
---
|
|
||||||
title: URL Scheme
|
|
||||||
---
|
|
||||||
# URLs in DAPP browsers
|
|
||||||
|
|
||||||
URLs should contain all allowable urls in browsers and _all_ `http(s)` urls that resolve in a usual browser must resolve the same way.
|
|
||||||
|
|
||||||
All urls not conforming to the existing urls scheme must still resemble the current urls scheme.
|
|
||||||
|
|
||||||
```
|
|
||||||
<protocol>://<source>/<path>
|
|
||||||
```
|
|
||||||
|
|
||||||
Irrespective of the main protocol, `<source>` should be resolved with our version of DNS (`NameReg` (ename registration contract on ethereum) and/or via swarm signed version stream.
|
|
||||||
|
|
||||||
In the special case of the bzz protocol, `<source>` must resolve to a Swarm hash of the content (in other words, the root key of the content). This content is assumed to be of mime type `application/bzz-sitemap+json` the only mime-type directly handled by Swarm.
|
|
||||||
|
|
||||||
# Swarm manifests
|
|
||||||
|
|
||||||
A Swarm manifest is a json formatted description of url routing.
|
|
||||||
The swarm manifest allows swarm documents to act as file systems or webservers.
|
|
||||||
Their mime type is `application/bzz-sitemap+json`
|
|
||||||
Manifest has the following attributes:
|
|
||||||
|
|
||||||
- `entries`: an array of route configurations
|
|
||||||
- `host`: eth host name registered (or to register) with NameReg
|
|
||||||
- `number`: position index (increasing integers) of manifest within channel,
|
|
||||||
- `auth`: devp2p cryptohandshake public key(s), signed number
|
|
||||||
- `first`: root key of initial state of the stream
|
|
||||||
- `previous`: previous state of stream
|
|
||||||
|
|
||||||
A route descriptor manifest entry json object has the following attributes:
|
|
||||||
|
|
||||||
- `path`: a path relative to the url that resolved to the manifest (_optional, with empty default_)
|
|
||||||
- `hash`: key of the content to be looked up by swarm (_optional_)
|
|
||||||
- `link`: relative path or external link (_optional_)
|
|
||||||
- `contentType`: mime type of the content (_optional, `application/bzz-server` by default_)
|
|
||||||
- `status`: optional http status code to pass back to the server (_optional, 200 by default_)
|
|
||||||
- `cache`: cache entry, etag? and other header options (_optional_)
|
|
||||||
- `www`: alternative old web address that the route replicates: e.g., `http://eth:bzz@google.com` (_optional_)
|
|
||||||
|
|
||||||
If `path` is an empty string or is missing, the path matches the _document-root_ of the DAPP.
|
|
||||||
If `contentType` is empty or missing, manifest if assumed by default.
|
|
||||||
|
|
||||||
(NOTE: Unclear. When no path matches and there is no fallback path e.g. a root `/` path with hash specified, it should return a simple 404 status code)
|
|
||||||
|
|
||||||
# Url resolution
|
|
||||||
|
|
||||||
Given
|
|
||||||
|
|
||||||
```
|
|
||||||
bzz://<source>/<path>
|
|
||||||
```
|
|
||||||
|
|
||||||
in the browser, the following steps need to happen:
|
|
||||||
|
|
||||||
- the browser sees that its bzz protocol `<source>/<path>` is passed to the *bzz protocol handler*,
|
|
||||||
- the handler checks if `<source>` is a hash. If not it resolves to a hash via NameReg and signed version table, see below
|
|
||||||
- the bzz protocol handler first retrieves the content for the hash (with integrity check) which it interprets as a manifest file (`application/bzz-sitemap+json`),
|
|
||||||
- this manifest file is then parsed, read and the json array element with the longest prefix `p` of `<path>` is looked up. I.e., `p` is the longest prefix such that `<path> == p'/p''`. (If the longest prefix is 0 length, the row with `<path> == ""` (or left out) is chosen.)
|
|
||||||
- as a special case, trailing forward slashes are ignored so all variants will match the directory,
|
|
||||||
- the protocol then looks up content for `p'` and serves it to the browser together with the status code and content type.
|
|
||||||
- if content is of type manifest, bzz retrieves it and repeats the steps using `p''` to match the manifest's `<path>` values against,
|
|
||||||
- the url relative path is set to `p''`
|
|
||||||
- if the url looked up is an old-world http site, then a standard http client call is sufficient.
|
|
||||||
|
|
||||||
### Example 1
|
|
||||||
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
entries: [
|
|
||||||
{
|
|
||||||
"path": "cv.pdf",
|
|
||||||
"contentType": "document/pdf",
|
|
||||||
"hash": "sdfhsd76ftsd86ft76sdgf78h7tg",
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
where the hash is the hash of the actual file `cv.pdf`.
|
|
||||||
|
|
||||||
If this manifest hashes to `dafghjfgsdgfjfgsdjfgsd`, then `bzz://dafghjfgsdgfjfgsdjfgsd/cv.pdf` will serve `cv.pdf`
|
|
||||||
|
|
||||||
Now you can register the manifest hash with NameReg to resolve `my-website` the file as follows:
|
|
||||||
|
|
||||||
```
|
|
||||||
http://my-website/cv.pdf
|
|
||||||
```
|
|
||||||
|
|
||||||
serves `cv.pdf`
|
|
||||||
|
|
||||||
### Example 2
|
|
||||||
Imagine you have a DAPP called _chat_ and host it under
|
|
||||||
your local directory `<dir>` looks like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
index.html
|
|
||||||
img/logo.gif
|
|
||||||
img/avatars/fefe.jpg
|
|
||||||
img/avatars/index.html
|
|
||||||
```
|
|
||||||
|
|
||||||
the webserver has the following routing rules:
|
|
||||||
|
|
||||||
```
|
|
||||||
-> <dir>/index.html
|
|
||||||
<unkwown> -> <dir>/index.html # where <unknown> != index.html
|
|
||||||
img/logo.gif -> <dir>/img/logo.gif
|
|
||||||
img/avatars -> <dir>img/avatars/index.html
|
|
||||||
img/avatars/fefe.jpg -> <dir>/img/avatars/fefe.jpg
|
|
||||||
img/avatars/<unknown>.jpg <dir>/img/avatars/index.html # where <unknown> != fefe.jpg
|
|
||||||
```
|
|
||||||
|
|
||||||
Now you can alternatively host your app in Swarm by creating the following manifest:
|
|
||||||
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
"entries": [
|
|
||||||
{ "hash": HASH(<dir>/index.html) },
|
|
||||||
{ "path": "index.html", "hash": HASH(<dir>/index.html) },
|
|
||||||
{ "path": "img/logo.gif", "hash": HASH(<dir>/img/logo.gif) },
|
|
||||||
{ "path": "img/avatars/", "hash": HASH(<dir>/img/avatars/index.html) },
|
|
||||||
{ "path": "img/avatars/fefe.jpg", "hash": HASH(img/avatars/fefe.jpg) }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
# Swarm webservers
|
|
||||||
|
|
||||||
Swarm webservers are simply bzz site manifest files routing relative paths to static assets.
|
|
||||||
Manifest route entries specify metadata: http header values, etag, redirects, links, etc.
|
|
||||||
|
|
||||||
In a typical scenario, the developer has a website within a working copy directory on their dev environment and they want to create a decentralised version of their site.
|
|
||||||
|
|
||||||
They then register the host domain with ethereum NameReg or swarm signed version stream, upload all desired static assets to swarm, and produce a site manifest.
|
|
||||||
|
|
||||||
In order to facilitate the creation of the manifest file for existing web projects, a native API and a command line utility are provided to automatically generate manifest files from a directory.
|
|
||||||
|
|
||||||
## ArcHive API
|
|
||||||
|
|
||||||
A native API and a command line utility are provided to automatically swarmify document collections.
|
|
||||||
constructor parameters:
|
|
||||||
|
|
||||||
- `template`: manifest template: the entries found in the directory scan are merged into this template to yield the resulting site-map. Note that this template can be considered a config file to the archiver.
|
|
||||||
|
|
||||||
The archiver can be called multiple times scanning multiple directories.
|
|
||||||
|
|
||||||
runtime parameters:
|
|
||||||
- `path`: path to directory relative routes in the template matched against directory paths under `path` (_optional_, '.' by default).
|
|
||||||
- `not-found`: errorchange to be used when asset is not found: for 404, (_optional_, `index.html`)
|
|
||||||
- `register-names` use eth NameReg to register public key and this version is pushed to swarm mutable store (_optional_, _false_)
|
|
||||||
- `without-scan` only consider paths given in template (_optional_, by default _false_: in template, scan directory and add/merge all readable content to manifest)
|
|
||||||
- `without-upload`: files are not uploaded, only hashes are calculated and manifest is created (_optional_, _false_, upload every asset to swarm)
|
|
||||||
|
|
||||||
If both `without-scan` and `without-upload` are omitted then `path` is used to associate files, extend the manifest entries, and upload content.
|
|
||||||
|
|
||||||
if `register-names` is set all named nodes.
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"path": "chat",
|
|
||||||
"hash": "sdfhsd76ftsd86ft76sdgf78h7tg",
|
|
||||||
"status": 200,
|
|
||||||
"contentType": "document/pdf"
|
|
||||||
},
|
|
||||||
...
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Without swarm, the zip fallback
|
|
||||||
|
|
||||||
namereg resolution:
|
|
||||||
|
|
||||||
`contentOf('eth/wallet') -> 324234kj23h4kj2h3kj423kj4h23`
|
|
||||||
|
|
||||||
This name reg has also a `urlOf` where it can find the file (e.g. from a raw pastebin)
|
|
||||||
|
|
||||||
It then downloads the file, extracts it and resolves all relative/absolute paths, based on the manifest it finds in it.
|
|
||||||
|
|
||||||
For the developer, the upload mechanism in mix will be the same, as he chooses a folder and can provide a `serverconfig.json` (or manfiest)
|
|
||||||
|
|
||||||
The only difference is the lookup and where it gets the files from.
|
|
||||||
|
|
||||||
```
|
|
||||||
swarm -> content hashes
|
|
||||||
before swarm -> zip file content
|
|
||||||
```
|
|
||||||
|
|
||||||
And both are resolved through the same manifest scheme
|
|
||||||
|
|
||||||
## Server config examples:
|
|
||||||
|
|
||||||
URL: bzz://dsf32f3cdsfsd/somefolder/other
|
|
||||||
Same as: eth://myname.reggae/somefolder/other
|
|
||||||
|
|
||||||
We should also map folder with and without "/" so that the path lookup for path: "/something/myfolder" is the same as "/something/myfolder/"
|
|
||||||
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
previous: 'jgjgj67576576576567ytjy',
|
|
||||||
first: 'ds564rh5656hhfghfg',
|
|
||||||
entries:[{
|
|
||||||
// Custom error page
|
|
||||||
path: '/i18n/',
|
|
||||||
file: '/errorpages/404.html',
|
|
||||||
// parses "file" when processing the folder and add: hash: '7685trgdrreewr34f34', contentType: 'text/html'
|
|
||||||
status: 404
|
|
||||||
|
|
||||||
},{
|
|
||||||
// custom fallback file for this folder: "/images/sdffsdfds/"
|
|
||||||
path: '/images/sdffsdfds/',
|
|
||||||
file: '/index.html',
|
|
||||||
// parses "file" when processing the folder and add: hash: '345678678678678678tryrty', contentType: 'text/html'
|
|
||||||
|
|
||||||
},{
|
|
||||||
// custom fallback file with custom header.
|
|
||||||
path: '/',
|
|
||||||
file: '/index.html',
|
|
||||||
// parses "file" when processing the folder and add: hash: '434534534f34k234234hrkj34hkjrh34', contentType: 'text/html'
|
|
||||||
status: 500
|
|
||||||
|
|
||||||
},{
|
|
||||||
// redirect (changing url after?)
|
|
||||||
path: '/somefolder/',
|
|
||||||
redirect: 'http://google.com'
|
|
||||||
|
|
||||||
},{
|
|
||||||
// linking?
|
|
||||||
path: '/somefolder/other/',
|
|
||||||
link: 'bzz://43greg45gerg5t45gerge/chat/' // hash to another manifest
|
|
||||||
|
|
||||||
},{
|
|
||||||
// downloading a file by pointing to a folder
|
|
||||||
path: '/somefolder/other/',
|
|
||||||
file: '/mybook.pdf',
|
|
||||||
// parses "file" when processing the folder and add: hash: '645325ytrhfgdge4tgre43f34', BUT no contentType, as its already present
|
|
||||||
contentType: 'application/octet-stream' // trigger a download in the browser for this link)
|
|
||||||
|
|
||||||
},{
|
|
||||||
// downloading
|
|
||||||
path: '/test.html',
|
|
||||||
file: '/test.html',
|
|
||||||
// parses "file" when processing the folder and add: hash: '645325ytrhfgdge4tgre43f34', BUT no contentType, as its already present
|
|
||||||
contentType: 'application/octet-stream' // trigger a download in the browser for this link)
|
|
||||||
|
|
||||||
// automatic generated files
|
|
||||||
},{
|
|
||||||
path: '/i18n/app.en.json',
|
|
||||||
hash: '456yrtgfds43534t45',
|
|
||||||
contentType: 'text/json',
|
|
||||||
},{
|
|
||||||
path: '/somefolder/other/image.png',
|
|
||||||
hash: '434534534f34khrkj34hkjrh34',
|
|
||||||
contentType: 'image/png',
|
|
||||||
},{
|
|
||||||
path: '/somefolder/other/343242.png',
|
|
||||||
hash: '434534534f34k234234hrkj34hkjrh34',
|
|
||||||
contentType: 'image/png',
|
|
||||||
},{
|
|
||||||
path: '/somefold/frau.png',
|
|
||||||
hash: 'sdfsdfsdfsdfsdfsdfsd',
|
|
||||||
contentType: 'image/png',
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
@ -1,121 +0,0 @@
|
||||||
---
|
|
||||||
title: Creating your own Ethereum apps using Eth go
|
|
||||||
---
|
|
||||||
|
|
||||||
**This page is heavily outdated**
|
|
||||||
|
|
||||||
The modular nature of Go and the Ethereum Go implementation 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 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.
|
|
||||||
|
|
||||||
```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!
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
see here https://github.com/ethersphere/go-ethereum/wiki/IPFS--SWARM
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
---
|
|
||||||
title: Swarm TODO
|
|
||||||
---
|
|
||||||
# Sprint plan
|
|
||||||
|
|
||||||
# scope
|
|
||||||
- forwarding only (no recursive lookup and no connecting to new nodes, only working with active peers)
|
|
||||||
|
|
||||||
## TODO
|
|
||||||
|
|
||||||
- integrate new p2p
|
|
||||||
- write unit tests for protocol and netstore (without protocol)
|
|
||||||
- rework protocol errors using errs after PR merged
|
|
||||||
- integrate new p2p or develop branch after p2p merge
|
|
||||||
- integrate cademlia into hive / peer pool with new p2p
|
|
||||||
- work out timeouts and timeout encoding
|
|
||||||
- cli tools
|
|
||||||
- url bar and proxy
|
|
||||||
|
|
||||||
## CLI
|
|
||||||
- hooking into DPA local API
|
|
||||||
- running as a daemon accepting request via socket?
|
|
||||||
|
|
||||||
### -
|
|
||||||
## Encryption
|
|
||||||
- encryption gateway to incentivise encryption of public content
|
|
||||||
- xor encryption with random chunks
|
|
||||||
- in-memory encryption keys
|
|
||||||
- originator encryption for private content
|
|
||||||
|
|
||||||
|
|
||||||
## APIs
|
|
||||||
- DAPP API - js integration (Fabian, Alex)
|
|
||||||
- mist dapp storage scheme, url->hash mapping (Fabian, Alex) [URL scheme](../doc/url-scheme)
|
|
||||||
|
|
||||||
# Discuss alternatives
|
|
||||||
|
|
||||||
I suggest we each pick 2/3 and read up on their project status, features, useability, objectives, etc
|
|
||||||
- Is it even worth it to reinvent/reimplement the wheel?
|
|
||||||
- what features do we want now and in future
|
|
||||||
- roadmap
|
|
||||||
|
|
||||||
# Brainstorming
|
|
||||||
|
|
||||||
- storage economy, incentivisation, examples:
|
|
||||||
-- content owner pays recurring ether fee for storage.
|
|
||||||
-- scheme to reward content owner each time content is accessed. i.e accessing content would requires fee. this would reward popular content. should be optional though.
|
|
||||||
- dht - chain interaction
|
|
||||||
- proof of custody https://docs.google.com/document/d/1F81ulKEZFPIGNEVRsx0H1gl2YRtf0mUMsX011BzSjnY/edit
|
|
||||||
- proof of resources http://systemdocs.maidsafe.net/content/system_components/proof_of_resources.html
|
|
||||||
- nonoutsourceable proofs of storage as mining criteria
|
|
||||||
- proof of storage capacity directly rewarded by contract
|
|
||||||
- streaming, hash chains
|
|
||||||
- routing and learning graph traversal
|
|
||||||
- minimising hops
|
|
||||||
- forwarding strategies, optimising dispersion of requests
|
|
||||||
- lifetime of requests, renewals (repeated retrieval requests), expiry, reposting (repeated storage request)
|
|
||||||
- redundancy - store same data in multiple nodes (e.g 4x)
|
|
||||||
- the more accessed a content is, the more available it should be, should increase performance for popular content.
|
|
||||||
|
|
||||||
# Simulations
|
|
||||||
|
|
||||||
- full table homogeneous nodes network size vs density vs table size expected row-sizes
|
|
||||||
- forwarding strategy vs latency vs traffic
|
|
||||||
- stable table, dropout rate vs routing optimisation by precalculating subtables for all peers. expected distance change (proximity delta) per hop
|
|
||||||
|
|
||||||
|
|
||||||
## Swarm
|
|
||||||
|
|
||||||
How far does the analogy go?
|
|
||||||
|
|
||||||
swarm of bees | a decentralised network of peers
|
|
||||||
-------|------------
|
|
||||||
living in a hive | form a distributed preimage archive
|
|
||||||
where they | where they
|
|
||||||
gather pollen | gather data chunks which they
|
|
||||||
to produce honey | transform into a longer data stream (document)
|
|
||||||
they consume and store | they serve and store
|
|
||||||
buzzing bzz | using bzz as their communications protocol
|
|
||||||
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
---
|
|
||||||
title: Swarm - distributed preimage archive
|
|
||||||
---
|
|
||||||
# Resources
|
|
||||||
|
|
||||||
## Swarm, the name
|
|
||||||
- https://www.facebook.com/swarmcorp, http://swarm.fund/
|
|
||||||
- https://bitcointalk.org/index.php?topic=650143.0
|
|
||||||
- https://bitcoinmagazine.com/17956/swarm-1-rick-falkvinges-swarmops-project/
|
|
||||||
- http://www.amazon.co.uk/Swarmwise-Tactical-Manual-Changing-World/dp/1463533152/
|
|
||||||
|
|
||||||
## Docs & specs
|
|
||||||
- [Swarm TODO](./swarm-todo)
|
|
||||||
- Dani & Viktor on public wiki: https://github.com/ethereum/wiki/wiki/Distributed-Preimage-Archive
|
|
||||||
- Dani on swarm hash: https://github.com/ethereum/wiki/wiki/Swarm-Hash
|
|
||||||
- Dani on incentive system: https://github.com/ethersphere/swarm/blob/master/doc/incentives.md
|
|
||||||
- The swarm smart contract
|
|
||||||
- gav on url-hint https://github.com/ethereum/wiki/wiki/URL-Hint-Protocol
|
|
||||||
- Gav on public wiki: https://github.com/ethereum/cpp-ethereum/wiki/Swarm
|
|
||||||
- network (DEVp2p)
|
|
||||||
- [Peer-to-Peer](../developers/peer-to-peer)
|
|
||||||
- on kademlia: https://github.com/ethereum/wiki/wiki/Cademlia-Peer-Selection
|
|
||||||
|
|
||||||
## Talks
|
|
||||||
- https://twitter.com/ethereumproject/status/538030376858693633
|
|
||||||
- Dr. Daniel Nagy: Ethereum ÐΞVcon-0: Keeping the Public Record Safe and Accessible - https://www.youtube.com/watch?v=QzYZQ03ON2o&list=PLJqWcTqh_zKEjpSej3ddtDOKPRGl_7MhS&index=7&spfreload=10
|
|
||||||
|
|
||||||
## Forum
|
|
||||||
- empty as of 01/2015: https://forum.ethereum.org/categories/swarm
|
|
||||||
-
|
|
||||||
|
|
||||||
## Mentions, discussions
|
|
||||||
- http://www.reddit.com/r/ethereum/comments/2d4uyw/swarm_and_whisper/
|
|
||||||
- http://www.reddit.com/r/ethereum/comments/2ityfz/ethereum_swarm/
|
|
||||||
- https://www.maidsafe.org/t/ethereums-swarm-p2p-storage-and-whisper-p2p-messaging/1528
|
|
||||||
- Vitalik's blogpost of 08/2014 - https://blog.ethereum.org/2014/08/16/secret-sharing-erasure-coding-guide-aspiring-dropbox-decentralizer/
|
|
||||||
- Vitalik: 'Swarm is out-of-scope': https://www.reddit.com/r/ethereum/comments/2phvml/constructive_criticism_of_ethereum_project_not/cmwtfqq
|
|
||||||
- Vitalik on eth components, swarm at 4:00 http://www.naation.com/2015/02/02/ethereum-explained-with-vitalik-buterin-inventor-and-leader-of-the-ethereum-project/5764/
|
|
||||||
- https://www.youtube.com/watch?v=zgkmQ-jQJHk&feature=youtu.be
|
|
||||||
|
|
||||||
## Media
|
|
||||||
- https://twitter.com/jeffehh/status/565927366271467521
|
|
||||||
- https://twitter.com/avsa/status/566255260713627648
|
|
||||||
- https://twitter.com/zeligf/status/566042020909973504
|
|
||||||
- https://www.reddit.com/r/ethereum/comments/2wryru/eli5_how_is_ethereum_supposed_to_be_a_dropbox
|
|
||||||
- https://forum.ethereum.org/discussion/comment/7593/#Comment_7593
|
|
||||||
|
|
||||||
## Code
|
|
||||||
- bzz PR: https://github.com/ethereum/go-ethereum/pull/255,
|
|
||||||
- repo https://github.com/ethersphere/go-ethereum/tree/bzz/
|
|
||||||
- ethereum p2p: https://github.com/ethereum/go-ethereum/p2p
|
|
||||||
- peer selection, peer pool: https://github.com/ethereum/go-ethereum/pull/253
|
|
||||||
- p2p cademlia branch (discontinued): https://github.com/ethersphere/go-ethereum/tree/kademlia
|
|
||||||
- Felix's node discovery code: https://github.com/ethereum/go-ethereum/tree/develop/p2p/discover
|
|
||||||
|
|
||||||
# Alternatives
|
|
||||||
|
|
||||||
- storj - http://storj.io/
|
|
||||||
- maidsafe - http://maidsafe.net/
|
|
||||||
- ipfs - http://ipfs.io/, https://www.youtube.com/watch?v=Fa4pckodM9g, http://static.benet.ai/t/ipfs.pdf, https://github.com/jbenet/go-ipfs, https://www.youtube.com/watch?v=8CMxDNuuAiQ, https://www.reddit.com/r/ethereum/comments/2wot2i/ipfs_alpha_demo/
|
|
||||||
- filecoin - http://filecoin.io/
|
|
||||||
- permacoin - https://www.cs.umd.edu/~elaine/docs/permacoin.pdf, https://bitcointalk.org/index.php?topic=640410.0, http://blog.dshr.org/2014/06/permacoin.html
|
|
||||||
- siacoin - http://www.siacoin.com/
|
|
||||||
- riak - http://basho.com/riak/
|
|
||||||
- BitTorrent http://www.bittorrent.com/ maelstrom http://blog.bittorrent.com/2014/12/10/project-maelstrom-the-internet-we-build-next/
|
|
||||||
- Tahoe-LAFS https://www.tahoe-lafs.org/trac/tahoe-lafs
|
|
||||||
- retroshare http://retroshare.sourceforge.net/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,105 +0,0 @@
|
||||||
---
|
|
||||||
title: Geth
|
|
||||||
---
|
|
||||||
`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://ethereum.gitbooks.io/frontier-guide/content/frontier.html)
|
|
||||||
|
|
||||||
## 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](../install-and-build/build-from-source) for binary and scripted installs.
|
|
||||||
|
|
||||||
Developers and community enthusiast are advised to read the [Developers' Guide](../install-and-build/developers-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](../interface/javascript-console) includes the `web3` javascript Ðapp API as well as an additional admin API.
|
|
||||||
* JSON-RPC server: `geth` can be launched with a server that exposes the [JSON-RPC API](https://github.com/ethereum/wiki/wiki/JSON-RPC)
|
|
||||||
* [Command line options](../interface/command-line-options) documents command line parameters as well as subcommands.
|
|
||||||
|
|
||||||
## Basic Use Case Documentation
|
|
||||||
|
|
||||||
* [Managing accounts](../interface/managing-your-accounts)
|
|
||||||
* [Mining](../legacy/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/master/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
|
|
||||||
|
|
||||||
### 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/geth)
|
|
||||||
|
|
||||||
### Dapp developers' mailing list
|
|
||||||
|
|
||||||
https://dapplist.net/
|
|
||||||
|
|
||||||
### Helpdesk
|
|
||||||
|
|
||||||
On gitter, irc, skype or mail to helpdesk@ethereum.org
|
|
||||||
Loading…
Reference in a new issue